/* * Copyright (C) 2013 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.doomonafireball.betterpickers.timezonepicker; import com.doomonafireball.betterpickers.R; import android.content.Context; import android.graphics.Typeface; import android.graphics.drawable.Drawable; import android.text.Editable; import android.text.Spannable; import android.text.SpannableStringBuilder; import android.text.TextWatcher; import android.text.style.ImageSpan; import android.util.AttributeSet; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; import android.view.inputmethod.InputMethodManager; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.AutoCompleteTextView; import android.widget.ImageButton; import android.widget.LinearLayout; import android.widget.ListView; public class TimeZonePickerView extends LinearLayout implements TextWatcher, OnItemClickListener, OnClickListener { private static final String TAG = "TimeZonePickerView"; private Typeface mSansSerifLightTypeface; private Context mContext; private AutoCompleteTextView mAutoCompleteTextView; private TimeZoneFilterTypeAdapter mFilterAdapter; private boolean mHideFilterSearchOnStart = false; private boolean mFirstTime = true; TimeZoneResultAdapter mResultAdapter; private ImageButton mClearButton; public interface OnTimeZoneSetListener { void onTimeZoneSet(TimeZoneInfo tzi); } public TimeZonePickerView(Context context, AttributeSet attrs, String timeZone, long timeMillis, OnTimeZoneSetListener l, boolean hideFilterSearch) { super(context, attrs); mContext = context; LayoutInflater inflater = (LayoutInflater) context.getSystemService( Context.LAYOUT_INFLATER_SERVICE); inflater.inflate(R.layout.timezonepickerview, this, true); mSansSerifLightTypeface = Typeface.createFromAsset(context.getAssets(), "fonts/Roboto-Light.ttf"); mHideFilterSearchOnStart = hideFilterSearch; TimeZoneData tzd = new TimeZoneData(mContext, timeZone, timeMillis); mResultAdapter = new TimeZoneResultAdapter(mContext, tzd, l); ListView timeZoneList = (ListView) findViewById(R.id.timezonelist); timeZoneList.setAdapter(mResultAdapter); timeZoneList.setOnItemClickListener(mResultAdapter); mFilterAdapter = new TimeZoneFilterTypeAdapter(mContext, tzd, mResultAdapter); mAutoCompleteTextView = (AutoCompleteTextView) findViewById(R.id.searchBox); mAutoCompleteTextView.setTypeface(mSansSerifLightTypeface); mAutoCompleteTextView.addTextChangedListener(this); mAutoCompleteTextView.setOnItemClickListener(this); mAutoCompleteTextView.setOnClickListener(this); updateHint(R.string.hint_time_zone_search, R.drawable.ic_search_holo_light); mClearButton = (ImageButton) findViewById(R.id.clear_search); mClearButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { mAutoCompleteTextView.getEditableText().clear(); } }); } public void showFilterResults(int type, String string, int time) { if (mResultAdapter != null) { mResultAdapter.onSetFilter(type, string, time); } } public boolean hasResults() { return mResultAdapter != null && mResultAdapter.hasResults(); } public int getLastFilterType() { return mResultAdapter != null ? mResultAdapter.getLastFilterType() : -1; } public String getLastFilterString() { return mResultAdapter != null ? mResultAdapter.getLastFilterString() : null; } public int getLastFilterTime() { return mResultAdapter != null ? mResultAdapter.getLastFilterType() : -1; } public boolean getHideFilterSearchOnStart() { return mHideFilterSearchOnStart; } private void updateHint(int hintTextId, int imageDrawableId) { String hintText = getResources().getString(hintTextId); Drawable searchIcon = getResources().getDrawable(imageDrawableId); SpannableStringBuilder ssb = new SpannableStringBuilder(" "); // for the icon ssb.append(hintText); int textSize = (int) (mAutoCompleteTextView.getTextSize() * 1.25); searchIcon.setBounds(0, 0, textSize, textSize); ssb.setSpan(new ImageSpan(searchIcon), 1, 2, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); mAutoCompleteTextView.setHint(ssb); } // Implementation of TextWatcher @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } // Implementation of TextWatcher @Override public void onTextChanged(CharSequence s, int start, int before, int count) { if (mFirstTime && mHideFilterSearchOnStart) { mFirstTime = false; return; } filterOnString(s.toString()); } // Implementation of TextWatcher @Override public void afterTextChanged(Editable s) { if (mClearButton != null) { mClearButton.setVisibility(s.length() > 0 ? View.VISIBLE : View.GONE); } } @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { // Hide the keyboard since the user explicitly selected an item. InputMethodManager manager = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE); manager.hideSoftInputFromWindow(mAutoCompleteTextView.getWindowToken(), 0); // An onClickListener for the view item because I haven't figured out a // way to update the AutoCompleteTextView without causing an infinite loop. mHideFilterSearchOnStart = true; mFilterAdapter.onClick(view); } @Override public void onClick(View v) { if (mAutoCompleteTextView != null && !mAutoCompleteTextView.isPopupShowing()) { filterOnString(mAutoCompleteTextView.getText().toString()); } } // This method will set the adapter if no adapter has been set. The adapter is initialized // here to prevent the drop-down from appearing uninvited on orientation change, as the // AutoCompleteTextView.setText() will trigger the drop-down if the adapter has been set. private void filterOnString(String string) { if (mAutoCompleteTextView.getAdapter() == null) { mAutoCompleteTextView.setAdapter(mFilterAdapter); } mHideFilterSearchOnStart = false; mFilterAdapter.getFilter().filter(string); } }