Last active
January 19, 2020 09:09
-
-
Save esabook/9490928cbeeb5ecb94848b4e7b09de04 to your computer and use it in GitHub Desktop.
expand autocomplete pupup dialog to separated popup dialog
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package ***; | |
import android.app.Dialog; | |
import android.content.Context; | |
import android.content.DialogInterface; | |
import android.support.annotation.NonNull; | |
import android.support.annotation.Nullable; | |
import android.support.annotation.StyleRes; | |
import android.support.v4.widget.SwipeRefreshLayout; | |
import android.support.v7.widget.SearchView; | |
import android.text.Editable; | |
import android.text.TextWatcher; | |
import android.view.MotionEvent; | |
import android.view.View; | |
import android.widget.AdapterView; | |
import android.widget.ArrayAdapter; | |
import android.widget.EditText; | |
import android.widget.ListView; | |
import android.widget.Spinner; | |
import java.security.InvalidParameterException; | |
import java.util.concurrent.atomic.AtomicReference; | |
/** | |
* {@link SearchablePopupDialog} is separate dialog window for showing selectable list and {@link SearchView}. | |
* use {@see registerFromView} to auto calling this dialog when view touched {@see onTouch} | |
* | |
* example usage: | |
* | |
* <pre><code> | |
* new SearchablePopupDialog(getContext) | |
* .registerFromView(mAutoCompleteTextView, mStringAdapter); | |
* | |
* ... | |
* | |
* new SearchablePopupDialog(getContext) | |
* * .registerFromView(mSpinner, mSpinnerStringAdapter); | |
* </code></pre> | |
*/ | |
public class SearchablePopupDialog extends Dialog | |
implements View.OnTouchListener, | |
View.OnFocusChangeListener, | |
SearchView.OnQueryTextListener, | |
AdapterView.OnItemClickListener, DialogInterface.OnShowListener { | |
private final static @StyleRes | |
int mTheme = R.style.AppTheme_PopupAlertDialog; | |
private final AtomicReference<EditText> mAttachedView = new AtomicReference<>(); | |
private final AtomicReference<ArrayAdapter<String>> mAdapter = new AtomicReference<>(); | |
private SearchView search; | |
private ListView listView; | |
private SwipeRefreshLayout refreshLayout; | |
public SearchablePopupDialog(View v) { | |
this(v.getContext()); | |
} | |
public SearchablePopupDialog(@NonNull Context context) { | |
this(context, mTheme); | |
} | |
public SearchablePopupDialog(@NonNull Context context, int themeResId) { | |
super(context, themeResId); | |
init(); | |
} | |
protected SearchablePopupDialog(@NonNull Context context, boolean cancelable, @Nullable OnCancelListener cancelListener) { | |
super(context, cancelable, cancelListener); | |
init(); | |
} | |
/** | |
* define default configuration for layout, behavior | |
*/ | |
void init() { | |
if (mAdapter.get() == null) | |
mAdapter.set(new ArrayAdapter<String>(getContext(), android.R.layout.simple_dropdown_item_1line)); | |
setContentView(R.layout.dialog_dropdown); | |
search = findViewById(R.id.search); | |
listView = findViewById(R.id.list_item); | |
refreshLayout = findViewById(R.id.swipe_refresh); | |
refreshLayout.setEnabled(false); | |
setCancelable(true); | |
setCanceledOnTouchOutside(true); | |
setOnShowListener(this); | |
} | |
@Override | |
public void setOnShowListener(@Nullable OnShowListener listener) { | |
super.setOnShowListener(listener); | |
} | |
/** | |
* Open {@link SearchablePopupDialog} with {@link View} | |
* | |
* @param v | |
* @param adapter | |
*/ | |
public void registerFromView(View v, ArrayAdapter<String> adapter) { | |
if (v instanceof EditText) { | |
v.setOnTouchListener(this); | |
mAttachedView.set((EditText) v); | |
mAdapter.set(adapter); | |
} else { | |
throw new InvalidParameterException("View is not instance of EditText"); | |
} | |
} | |
/** | |
* Open {@link SearchablePopupDialog} with {@link Spinner} | |
* | |
* @param spinner | |
* @param adapter | |
*/ | |
public void registerFromView(final Spinner spinner, final ArrayAdapter<String> adapter) { | |
spinner.setOnTouchListener(this); | |
mAdapter.set(adapter); | |
EditText editText = new EditText(spinner.getContext()); | |
mAttachedView.set(editText); | |
editText.addTextChangedListener(new TextWatcher() { | |
@Override | |
public void beforeTextChanged(CharSequence s, int start, int count, int after) { | |
} | |
@Override | |
public void onTextChanged(CharSequence s, int start, int before, int count) { | |
} | |
@Override | |
public void afterTextChanged(Editable s) { | |
spinner.setSelection(adapter.getPosition(s.toString())); | |
} | |
}); | |
try { | |
editText.setText(spinner.getSelectedItem().toString()); | |
} catch (Exception ignore) { | |
} | |
} | |
@Override | |
public boolean onTouch(View v, MotionEvent event) { | |
if (!isShowing()) | |
show(); | |
return true; | |
} | |
@Override | |
public void onFocusChange(View v, boolean hasFocus) { | |
if (hasFocus) | |
show(); | |
} | |
@Override | |
public boolean onQueryTextSubmit(String s) { | |
mAdapter.get().getFilter().filter(s); | |
return false; | |
} | |
@Override | |
public boolean onQueryTextChange(String s) { | |
mAdapter.get().getFilter().filter(s); | |
return false; | |
} | |
@Override | |
public void onItemClick(AdapterView<?> parent, View view, int position, long id) { | |
mAttachedView.get().setText(mAdapter.get().getItem(position)); | |
dismiss(); | |
} | |
/** | |
* reassign view configuration when dialog in showing | |
* | |
* @param dialog | |
*/ | |
@Override | |
public void onShow(DialogInterface dialog) { | |
listView.setAdapter(mAdapter.get()); | |
mAdapter.get().notifyDataSetChanged(); | |
listView.setOnItemClickListener(this); | |
search.setOnQueryTextListener(this); | |
search.setQuery(mAttachedView.get().getText(), true); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment