Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 25ee07c2 authored by James Kung's avatar James Kung
Browse files

City Search functionality

Change-Id: I8ec790fe7adf59f81caf74af8be50d2fcfbd6b99
parent 28f4040a
Loading
Loading
Loading
Loading
+5 −4
Original line number Original line Diff line number Diff line
@@ -20,8 +20,9 @@
    android:layout_width="match_parent"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_height="wrap_content"
    android:clickable="true"
    android:clickable="true"
    android:paddingLeft="8dip"
    android:paddingStart="8dip"
    android:paddingStart="8dip"
    android:paddingRight="32dip"
    android:paddingEnd="8dip"
    android:paddingEnd="32dip"
    android:paddingLeft="8dip"
    android:clipToPadding="false" />
    android:paddingRight="8dip"
    android:clipToPadding="false"
    />
+16 −24
Original line number Original line Diff line number Diff line
@@ -18,25 +18,24 @@
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_width="match_parent"
    android:gravity="center_vertical"
    android:gravity="center_vertical"
    android:paddingLeft="8dip"
    android:paddingStart="8dip"
    android:paddingRight="8dip"
    android:paddingEnd="8dip"
    android:background="?android:attr/selectableItemBackground"
    android:background="?android:attr/selectableItemBackground"
    android:layout_height="wrap_content"
    android:layout_height="wrap_content"
    android:minHeight="@dimen/cities_list_item_height"
    android:minHeight="@dimen/cities_list_item_height"
    android:orientation="horizontal">
    android:orientation="horizontal">
    <LinearLayout
    <CheckBox
        android:layout_width="0dip"
        android:id="@+id/city_onoff"
        android:layout_weight="1"
        android:clickable="false"
        android:layout_height="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical">
        android:layout_width="wrap_content" />
    <TextView
    <TextView
        android:id="@+id/city_name"
        android:id="@+id/city_name"
        style="@style/city_name"
        style="@style/city_name"
        android:textColor="@color/clock_white"
        android:textColor="@color/clock_white"
        android:paddingStart="16dip"
        android:layout_height="wrap_content"
        android:layout_height="wrap_content"
            android:layout_width="wrap_content"/>
        android:layout_width="0dip"
        android:layout_weight="1"
        android:ellipsize="start" />
    <TextView
    <TextView
        android:id="@+id/city_time"
        android:id="@+id/city_time"
        style="@style/city_time"
        style="@style/city_time"
@@ -44,10 +43,3 @@
        android:layout_height="wrap_content"
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"/>
        android:layout_width="wrap_content"/>
</LinearLayout>
</LinearLayout>
    <CheckBox
        android:id="@+id/city_onoff"
        android:clickable="false"
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"
        android:layout_gravity="center_vertical" />
</LinearLayout>
+7 −0
Original line number Original line Diff line number Diff line
@@ -15,6 +15,13 @@
-->
-->


<menu xmlns:android="http://schemas.android.com/apk/res/android">
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@+id/menu_item_search"
        android:title="@android:string/search_go"
        android:icon="@android:drawable/ic_menu_search"
        android:showAsAction="ifRoom"
        android:actionViewClass="android.widget.SearchView"
        android:imeOptions="actionSearch"
        android:orderInCategory="1" />
    <item android:id="@+id/menu_item_settings"
    <item android:id="@+id/menu_item_settings"
        android:title="@string/menu_item_settings"
        android:title="@string/menu_item_settings"
        android:icon="@android:drawable/ic_menu_preferences"
        android:icon="@android:drawable/ic_menu_preferences"
+157 −43
Original line number Original line Diff line number Diff line
@@ -18,22 +18,32 @@ package com.android.deskclock.worldclock;


import android.app.ActionBar;
import android.app.ActionBar;
import android.app.Activity;
import android.app.Activity;
import android.app.SearchableInfo;
import android.content.ActivityNotFoundException;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Context;
import android.content.Intent;
import android.content.Intent;
import android.os.Bundle;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.preference.PreferenceManager;
import android.text.Spannable;
import android.text.TextUtils;
import android.text.format.DateFormat;
import android.text.format.DateFormat;
import android.text.style.ForegroundColorSpan;
import android.view.LayoutInflater;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MenuItem;
import android.view.View;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.ViewGroup;
import android.view.inputmethod.EditorInfo;
import android.widget.BaseAdapter;
import android.widget.BaseAdapter;
import android.widget.CheckBox;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.ListView;
import android.widget.ListView;
import android.widget.SearchView;
import android.widget.SearchView.OnQueryTextListener;
import android.widget.SectionIndexer;
import android.widget.SectionIndexer;
import android.widget.TextView;
import android.widget.TextView;


@@ -43,7 +53,6 @@ import com.android.deskclock.R;
import com.android.deskclock.SettingsActivity;
import com.android.deskclock.SettingsActivity;
import com.android.deskclock.Utils;
import com.android.deskclock.Utils;


import java.text.Collator;
import java.util.ArrayList;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Calendar;
import java.util.HashMap;
import java.util.HashMap;
@@ -52,10 +61,16 @@ import java.util.TimeZone;
/**
/**
 * Cities chooser for the world clock
 * Cities chooser for the world clock
 */
 */
public class CitiesActivity extends Activity implements OnCheckedChangeListener, View.OnClickListener {
public class CitiesActivity extends Activity implements OnCheckedChangeListener,
        View.OnClickListener, OnQueryTextListener {


    /** This must be false for production.  If true, turns on logging,
    private static final String KEY_SEARCH_QUERY = "search_query";
        test code, etc. */
    private static final String KEY_SEARCH_MODE = "search_mode";

    /**
     * This must be false for production. If true, turns on logging, test code,
     * etc.
     */
    static final boolean DEBUG = false;
    static final boolean DEBUG = false;
    static final String TAG = "CitiesActivity";
    static final String TAG = "CitiesActivity";


@@ -65,20 +80,61 @@ public class CitiesActivity extends Activity implements OnCheckedChangeListener,
    private HashMap<String, CityObj> mUserSelectedCities;
    private HashMap<String, CityObj> mUserSelectedCities;
    private Calendar mCalendar;
    private Calendar mCalendar;


    private MenuItem mSearchMenu;
    private SearchView mSearchView;
    private StringBuffer mQueryTextBuffer = new StringBuffer();
    private boolean mSearchMode;

    /***
    /***
* Adapter for a list of cities with the respected time zone.
     * Adapter for a list of cities with the respected time zone. The Adapter
* The Adapter sorts the list alphabetically and create an indexer.
     * sorts the list alphabetically and create an indexer.
     ***/
     ***/


    private class CityAdapter extends BaseAdapter implements SectionIndexer {
    private class CityAdapter extends BaseAdapter implements Filterable, SectionIndexer {
        private static final String DELETED_ENTRY = "C0";
        private static final String DELETED_ENTRY = "C0";
        private Object [] mAllTheCitiesList;                      // full list of the cities
        private ArrayList<CityObj> mAllTheCitiesList; // full list of the cities
        private final HashMap<String, CityObj> mSelectedCitiesList; // Selected cities by the use
        private final HashMap<String, CityObj> mSelectedCitiesList;  // selected cities

        private ArrayList<CityObj> mDisplayedCitiesList;
        private final int mSpanColor;

        private final LayoutInflater mInflater;
        private final LayoutInflater mInflater;
        private boolean mIs24HoursMode; // AM/PM or 24 hours mode
        private boolean mIs24HoursMode; // AM/PM or 24 hours mode
        private Object[] mSectionHeaders;
        private Object[] mSectionHeaders;
        private Object[] mSectionPositions;
        private Object[] mSectionPositions;


        private Filter mFilter = new Filter() {

            @Override
            protected FilterResults performFiltering(CharSequence constraint) {
                FilterResults results = new FilterResults();
                String modifiedQuery = constraint.toString().trim().toUpperCase();

                if (TextUtils.isEmpty(modifiedQuery)) {
                    results.values = mAllTheCitiesList;
                    results.count = mAllTheCitiesList.size();
                    return results;
                }

                ArrayList<CityObj> filteredList = new ArrayList<CityObj>();
                for (CityObj city : mAllTheCitiesList) {
                     String cityName = city.mCityName.trim().toUpperCase();
                     if (city.mCityId != null && cityName.startsWith(modifiedQuery)) {
                         filteredList.add(city);
                     }
                }
                results.values = filteredList;
                results.count = filteredList.size();
                return results;
            }

            @Override
            protected void publishResults(CharSequence constraint, FilterResults results) {
                mDisplayedCitiesList = (ArrayList<CityObj>) results.values;
                notifyDataSetChanged();
            }
        };

        public CityAdapter(
        public CityAdapter(
                Context context, HashMap<String, CityObj> selectedList, LayoutInflater factory) {
                Context context, HashMap<String, CityObj> selectedList, LayoutInflater factory) {
            super();
            super();
@@ -87,18 +143,19 @@ public class CitiesActivity extends Activity implements OnCheckedChangeListener,
            mInflater = factory;
            mInflater = factory;
            mCalendar = Calendar.getInstance();
            mCalendar = Calendar.getInstance();
            mCalendar.setTimeInMillis(System.currentTimeMillis());
            mCalendar.setTimeInMillis(System.currentTimeMillis());
            mSpanColor = context.getResources().getColor(R.color.clock_blue);
            set24HoursMode(context);
            set24HoursMode(context);
        }
        }


        @Override
        @Override
        public int getCount() {
        public int getCount() {
            return (mAllTheCitiesList != null) ? mAllTheCitiesList.length : 0;
            return (mDisplayedCitiesList != null) ? mDisplayedCitiesList.size() : 0;
        }
        }


        @Override
        @Override
        public Object getItem(int p) {
        public Object getItem(int p) {
            if (mAllTheCitiesList != null && p >=0 && p < mAllTheCitiesList.length) {
            if (mDisplayedCitiesList != null && p >= 0 && p < mDisplayedCitiesList.size()) {
                return mAllTheCitiesList [p];
                return mDisplayedCitiesList.get(p);
            }
            }
            return null;
            return null;
        }
        }
@@ -110,16 +167,17 @@ public class CitiesActivity extends Activity implements OnCheckedChangeListener,


        @Override
        @Override
        public boolean isEnabled(int p) {
        public boolean isEnabled(int p) {
            return mAllTheCitiesList != null && ((CityObj)mAllTheCitiesList[p]).mCityId != null;
            return mDisplayedCitiesList != null && mDisplayedCitiesList.get(p).mCityId != null;
        }
        }


        @Override
        @Override
        public View getView(int position, View view, ViewGroup parent) {
        public View getView(int position, View view, ViewGroup parent) {
            if (mAllTheCitiesList == null || position < 0 || position >= mAllTheCitiesList.length) {
            if (mDisplayedCitiesList == null || position < 0
                    || position >= mDisplayedCitiesList.size()) {
                return null;
                return null;
            }
            }
            CityObj c = (CityObj)mAllTheCitiesList [position];
            CityObj c = mDisplayedCitiesList.get(position);
            // Header view (A CityObj with nothing but the first letter as the name
            // Header view: A CityObj with nothing but the first letter as the name
            if (c.mCityId == null) {
            if (c.mCityId == null) {
                if (view == null || view.findViewById(R.id.header) == null) {
                if (view == null || view.findViewById(R.id.header) == null) {
                    view = mInflater.inflate(R.layout.city_list_header, parent, false);
                    view = mInflater.inflate(R.layout.city_list_header, parent, false);
@@ -140,7 +198,7 @@ public class CitiesActivity extends Activity implements OnCheckedChangeListener,
                cb.setOnCheckedChangeListener(CitiesActivity.this);
                cb.setOnCheckedChangeListener(CitiesActivity.this);
                mCalendar.setTimeZone(TimeZone.getTimeZone(c.mTimeZone));
                mCalendar.setTimeZone(TimeZone.getTimeZone(c.mTimeZone));
                tz.setText(DateFormat.format(mIs24HoursMode ? "k:mm" : "h:mmaa", mCalendar));
                tz.setText(DateFormat.format(mIs24HoursMode ? "k:mm" : "h:mmaa", mCalendar));
                name.setText(c.mCityName);
                name.setText(c.mCityName, TextView.BufferType.SPANNABLE);
            }
            }
            return view;
            return view;
        }
        }
@@ -167,8 +225,8 @@ public class CitiesActivity extends Activity implements OnCheckedChangeListener,
                    continue;
                    continue;
                }
                }
                if (!city.mCityName.substring(0, 1).equals(val)) {
                if (!city.mCityName.substring(0, 1).equals(val)) {
                    val = city.mCityName.substring(0, 1);
                    val = city.mCityName.substring(0, 1).toUpperCase();
                    sections.add((new String(val)).toUpperCase());
                    sections.add(val);
                    positions.add(count);
                    positions.add(count);
                    // Add a header
                    // Add a header
                    items.add(new CityObj(val, null, null));
                    items.add(new CityObj(val, null, null));
@@ -179,7 +237,8 @@ public class CitiesActivity extends Activity implements OnCheckedChangeListener,
            }
            }
            mSectionHeaders = sections.toArray();
            mSectionHeaders = sections.toArray();
            mSectionPositions = positions.toArray();
            mSectionPositions = positions.toArray();
            mAllTheCitiesList = items.toArray();
            mAllTheCitiesList = items;
            mDisplayedCitiesList = items;
        }
        }


        @Override
        @Override
@@ -207,21 +266,36 @@ public class CitiesActivity extends Activity implements OnCheckedChangeListener,
        public Object[] getSections() {
        public Object[] getSections() {
            return mSectionHeaders;
            return mSectionHeaders;
        }
        }
    }


        @Override
        public Filter getFilter() {
            return mFilter;
        }
    }


    @Override
    @Override
    protected void onCreate(Bundle icicle) {
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(icicle);
        super.onCreate(savedInstanceState);
        mFactory = LayoutInflater.from(this);
        mFactory = LayoutInflater.from(this);
        if (savedInstanceState != null) {
            mQueryTextBuffer.append(savedInstanceState.getString(KEY_SEARCH_QUERY));
            mSearchMode = savedInstanceState.getBoolean(KEY_SEARCH_MODE);
        }
        updateLayout();
        updateLayout();
    }
    }


    @Override
    public void onSaveInstanceState(Bundle bundle) {
        super.onSaveInstanceState(bundle);
        bundle.putString(KEY_SEARCH_QUERY, mQueryTextBuffer.toString());
        bundle.putBoolean(KEY_SEARCH_MODE, mSearchMode);
    }

    private void updateLayout() {
    private void updateLayout() {
        setContentView(R.layout.cities_activity);
        setContentView(R.layout.cities_activity);
        mCitiesList = (ListView) findViewById(R.id.cities_list);
        mCitiesList = (ListView) findViewById(R.id.cities_list);
        mCitiesList.setFastScrollEnabled(true);
        mCitiesList.setFastScrollAlwaysVisible(true);
        mCitiesList.setFastScrollAlwaysVisible(true);
        mCitiesList.setFastScrollEnabled(TextUtils.isEmpty(mQueryTextBuffer.toString()));
        mCitiesList.setScrollBarStyle(View.SCROLLBARS_INSIDE_INSET);
        mCitiesList.setScrollBarStyle(View.SCROLLBARS_INSIDE_INSET);
        mUserSelectedCities = Cities.readCitiesFromSharedPrefs(
        mUserSelectedCities = Cities.readCitiesFromSharedPrefs(
                PreferenceManager.getDefaultSharedPreferences(this));
                PreferenceManager.getDefaultSharedPreferences(this));
@@ -241,7 +315,6 @@ public class CitiesActivity extends Activity implements OnCheckedChangeListener,
        }
        }
    }
    }



    @Override
    @Override
    public void onPause() {
    public void onPause() {
        super.onPause();
        super.onPause();
@@ -285,6 +358,33 @@ public class CitiesActivity extends Activity implements OnCheckedChangeListener,
        if (help != null) {
        if (help != null) {
            Utils.prepareHelpMenuItem(this, help);
            Utils.prepareHelpMenuItem(this, help);
        }
        }

        mSearchMenu = menu.findItem(R.id.menu_item_search);
        mSearchView = (SearchView) mSearchMenu.getActionView();
        mSearchView.setImeOptions(EditorInfo.IME_FLAG_NO_EXTRACT_UI);
        mSearchView.setOnSearchClickListener(new OnClickListener() {

            @Override
            public void onClick(View arg0) {
                mSearchMode = true;
            }
        });
        mSearchView.setOnCloseListener(new SearchView.OnCloseListener() {

            @Override
            public boolean onClose() {
                mSearchMode = false;
                return false;
            }
        });
        if (mSearchView != null) {
            mSearchView.setOnQueryTextListener(this);
            mSearchView.setQuery(mQueryTextBuffer.toString(), false);
            if (mSearchMode) {
                mSearchView.requestFocus();
                mSearchView.setIconified(false);
            }
        }
        return super.onCreateOptionsMenu(menu);
        return super.onCreateOptionsMenu(menu);
    }
    }


@@ -305,4 +405,18 @@ public class CitiesActivity extends Activity implements OnCheckedChangeListener,
        onCheckedChanged(b, checked);
        onCheckedChanged(b, checked);
        b.setChecked(!checked);
        b.setChecked(!checked);
    }
    }

    @Override
    public boolean onQueryTextChange(String queryText) {
        mQueryTextBuffer.setLength(0);
        mQueryTextBuffer.append(queryText);
        mCitiesList.setFastScrollEnabled(TextUtils.isEmpty(queryText.trim()));
        mAdapter.getFilter().filter(queryText);
        return true;
    }

    @Override
    public boolean onQueryTextSubmit(String arg0) {
        return false;
    }
}
}
+0 −2
Original line number Original line Diff line number Diff line
@@ -43,7 +43,6 @@ public class CityObj {
                '}';
                '}';
    }
    }



    public CityObj(SharedPreferences prefs, int index) {
    public CityObj(SharedPreferences prefs, int index) {
        mCityName = prefs.getString(CITY_NAME + index, null);
        mCityName = prefs.getString(CITY_NAME + index, null);
        mTimeZone = prefs.getString(CITY_TIME_ZONE + index, null);
        mTimeZone = prefs.getString(CITY_TIME_ZONE + index, null);
@@ -55,5 +54,4 @@ public class CityObj {
        editor.putString (CITY_TIME_ZONE + index, mTimeZone);
        editor.putString (CITY_TIME_ZONE + index, mTimeZone);
        editor.putString (CITY_ID + index, mCityId);
        editor.putString (CITY_ID + index, mCityId);
    }
    }

}
}