Possible to autocomplete a EditTextPreference? - android

Is it possible to have an EditTextPreference with AutoComplete attached to it?
I know ho to attach one to an element with an id, but am having trouble figure out how to attach the ArrayAdapter to the preference field.
This is wrong, but it's as close as I can get.
final String[] TEAMS = getResources().getStringArray(R.array.teams);
AutoCompleteTextView EditTextPreference = (AutoCompleteTextView) findViewById(R.id.editTextPrefTeam);
ArrayAdapter adapter = new ArrayAdapter(this, android.R.layout.simple_dropdown_item_1line, TEAMS);
EditTextPreference.setAdapter(adapter);

It seemed to me there had to be an "easier" way to accomplish this than by hacking into the EditTextPreference class and messing with the view. Here's my solution, since AutoCompleteTextView extends EditText, I only had to override the EditTextPreference methods that call their constant EditText object directly.
public class AutoCompletePreference extends EditTextPreference {
private static AutoCompleteTextView mEditText = null;
public AutoCompletePreference(Context context, AttributeSet attrs) {
super(context, attrs);
mEditText = new AutoCompleteTextView(context, attrs);
mEditText.setThreshold(0);
//The adapter of your choice
ArrayAdapter<String> adapter = new ArrayAdapter<String>(context, android.R.layout.simple_dropdown_item_1line, COUNTRIES);
mEditText.setAdapter(adapter);
}
private static final String[] COUNTRIES = new String[] {
"Belgium", "France", "Italy", "Germany", "Spain"
};
#Override
protected void onBindDialogView(View view) {
AutoCompleteTextView editText = mEditText;
editText.setText(getText());
ViewParent oldParent = editText.getParent();
if (oldParent != view) {
if (oldParent != null) {
((ViewGroup) oldParent).removeView(editText);
}
onAddEditTextToDialogView(view, editText);
}
}
#Override
protected void onDialogClosed(boolean positiveResult) {
if (positiveResult) {
String value = mEditText.getText().toString();
if (callChangeListener(value)) {
setText(value);
}
}
}
}
Thanks to Brady for linking to the source.

Here's a workaround I implemented by studying the EditTextPreference.java source code.
Essentially you need to subclass EditTextPreference and override when it binds to the dialog. At this point you can retrieve the EditText, copy it's values, and remove it from its parent view group. Then you inject your Autocompletetextview and hook up it's Arrayadapter.
public class AutoCompleteEditTextPreference extends EditTextPreference
{
public AutoCompleteEditTextPreference(Context context)
{
super(context);
}
public AutoCompleteEditTextPreference(Context context, AttributeSet attrs)
{
super(context, attrs);
}
public AutoCompleteEditTextPreference(Context context, AttributeSet attrs,
int defStyle)
{
super(context, attrs, defStyle);
}
/**
* the default EditTextPreference does not make it easy to
* use an AutoCompleteEditTextPreference field. By overriding this method
* we perform surgery on it to use the type of edit field that
* we want.
*/
protected void onBindDialogView(View view)
{
super.onBindDialogView(view);
// find the current EditText object
final EditText editText = (EditText)view.findViewById(android.R.id.edit);
// copy its layout params
LayoutParams params = editText.getLayoutParams();
ViewGroup vg = (ViewGroup)editText.getParent();
String curVal = editText.getText().toString();
// remove it from the existing layout hierarchy
vg.removeView(editText);
// construct a new editable autocomplete object with the appropriate params
// and id that the TextEditPreference is expecting
mACTV = new AutoCompleteTextView(getContext());
mACTV.setLayoutParams(params);
mACTV.setId(android.R.id.edit);
mACTV.setText(curVal);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(getContext(),
android.R.layout.simple_dropdown_item_1line, [LIST OF DATA HERE]);
mACTV.setAdapter(adapter);
// add the new view to the layout
vg.addView(mACTV);
}
/**
* Because the baseclass does not handle this correctly
* we need to query our injected AutoCompleteTextView for
* the value to save
*/
protected void onDialogClosed(boolean positiveResult)
{
super.onDialogClosed(positiveResult);
if (positiveResult && mACTV != null)
{
String value = mACTV.getText().toString();
if (callChangeListener(value)) {
setText(value);
}
}
}
/**
* again we need to override methods from the base class
*/
public EditText getEditText()
{
return mACTV;
}
private AutoCompleteTextView mACTV = null;
private final String TAG = "AutoCompleteEditTextPreference";
}

Probably if you subclass it and make your own view for that and use the AutoCompleteTextView object as element it will work, as currently I don't see how a simple EditText can be changed to autocomplete.

Related

How to create big dynamic view in android?

i have a big problem with creating and removing views in many times
For example i searched in sqlite database and fetching 200 records, and i want create 200view in my activity but it happen in 3 or 4 seconds and it is bad for user experiences and performances.how to increase time for creating views every time?
These are my codes for creating views
public class CreateView {
boolean header_flag=false;
boolean first_widget=false;
LinearLayout header_layout;
List<Words_taha> words_tahaList=new ArrayList<>();
public void createHeader(Context context, LinearLayout main_layout, Words_taha words){
if(header_flag==false){
header_layout =new LinearLayout(context);
header_layout=new LinearLayout(context);
header_layout.setOrientation(LinearLayout.HORIZONTAL);
header_layout.setBackgroundResource(R.mipmap.sure_template);
header_layout.setId(words.getW_id());
header_layout.setGravity(Gravity.CENTER);
main_layout.addView(header_layout);
header_flag=true;
words_tahaList.add(words);
}
else {
words_tahaList.add(words);
Collections.reverse(words_tahaList);
for(int i=0;words_tahaList.size()>i;i++){
TextView textView=new TextView(context);
textView.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT));
textView.setText(words_tahaList.get(i).getW_text()+" ");
textView.setTag(words_tahaList.get(i).getW_id());
Typeface typeface=Typeface.createFromAsset(context.getAssets(),"fonts/arabicNeirizi.ttf");
textView.setTypeface(typeface);
textView.setTextColor(Color.parseColor("#000000"));
header_layout.addView(textView);
}
words_tahaList.clear();
header_flag=false;
}
}
public void createLabelForMainWordsInOneLine(Activity context, LinearLayout main_layout, List<Words_taha> words_tahaList, int count ){
LinearLayout linearLayout=new LinearLayout(context);
linearLayout.setOrientation(LinearLayout.HORIZONTAL);
linearLayout.setGravity(Gravity.CENTER);
if(words_tahaList.size()>0) {
main_layout.addView(linearLayout);
Collections.reverse(words_tahaList);
for (Words_taha w : words_tahaList) {
DroidTextView textView = new DroidTextView(context);
textView.setText(w.getW_text());
textView.setTag(w.getW_id());
textView.setTextColor(Color.parseColor("#000000"));
if (w.getW_type() == 3) {
textView.setLayoutParams(new LinearLayout.LayoutParams(130, 130));
textView.setGravity(Gravity.CENTER);
textView.setBackgroundResource(R.mipmap.sore);
} else {
textView.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT));
}
linearLayout.addView(textView);
}
words_tahaList.clear();
}
}
Please help me how to optimization my code
Thanks.
Well there are a views in android that made for this specific purpose, like ListView or RecyclerView and more, those views get Adapter object, the Adapter restore the data (in your case your 200 rows) and ListView For Example create only the Items That apear in the screen, And when the user scroll up ro down, ListView create the new Views that apear and delete the olds, this give to the user a fantastic use in huge lists of items, I recommend to lern use with ListView and Adapter if you must use your own custom View you can extends from ListView and implemnt in your own way.
you can read more here
if your want specific gui that diffrent from ListView or you need help let me know
Update :
if you want to create your own impl what do you think about this direction ?
public abstract class CustomBookView extends LinearLayout implements CustomBookListener {
private int pageIndex = 0;
private List<WordsTasa> wordsList;
public CustomBookView(Context context, int pageIndex, List<WordsTasa> wordsList) {
super(context);
this.pageIndex = pageIndex;
this.wordsList = wordsList;
}
public abstract View createPage(WordsTasa wordsTasa);
#Override
public void goNextPage() {
if(wordsList.size()>=pageIndex+1)
return;
this.removeAllViews();
//add your animation
this.addView(createPage(wordsList.get(++pageIndex)));
}
#Override
public void goPreviousPage() {
if(0<pageIndex-1)
return;
this.removeAllViews();
//add your animation
this.addView(createPage(wordsList.get(--pageIndex)));
}
public int getPageIndex() {
return pageIndex;
}
public void setPageIndex(int pageIndex) {
this.pageIndex = pageIndex;
}
public List<WordsTasa> getWordsList() {
return wordsList;
}
public void setWordsList(List<WordsTasa> wordsList) {
this.wordsList = wordsList;
}
public CustomBookView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CustomBookView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public static class WordsTasa {
private String words;
public WordsTasa(String words) {
this.words = words;
}
public String getWords() {
return words;
}
public void setWords(String words) {
this.words = words;
}
}
}
public interface CustomBookListener {
void goNextPage();
void goPreviousPage();
}
on your next page button or previous
button.setOnClickListener(new View.OnClickListener {
public void onClick(View v) {
customBookListener.goNextPage();
}
})

Select edittexts text in a listview. How can be done? I can't find out

I have a ListView with an EditText on each row working.
I need to select this text on click the edittext to write numbers without erasing or moving the cursor.
Using selectAllonfocus at first works. However, after scrolling the listview, the EditText got crazy and selection doesn't work correctly.
If I execute selectAll in the listener onFocus, then when a touch is made the contextmenu (select word, select all,etc) is shown instead of the selection.
If someone can help.
Thanks.
I can't tell what it is that you are trying to do. Perhaps it'd help if you can post some of your relevant source code...
But the fact that it gets crazy when you start scrolling makes me thing you aren't handling the convertView correctly in your adapter getView() method.
If you're having problem after scrolling it's the view recycling that's messing you up. You basically need to set up an array to hold the contents of the EditTexts so when you scroll they don't get messed up. You didn't say what was backing your list, but I've got a list with edittexts contained and here's how I handle it (from a cursor, but you could adapt it for an ArrayAdapter):
public class CursorAdapter_EditText extends SimpleCursorAdapter {
private static Cursor c;
private Context context;
public static String[] quantity;
private int layout;
public CursorAdapter_EditText(Context context, int layout, Cursor c,
String[] from, int[] to) {
super(context, layout, c, from, to);
CursorAdapter_EditText.c = c;
this.context = context;
this.layout = layout;
initializeQuantity(); // Call method to initialize array to hold edittext info
}
public static void initializeQuantity() {
quantity = new String[c.getCount()]; // Initialize array to proper # of items
int i = 0;
while (i < c.getCount()) {
quantity[i] = ""; // set all EditTexts to empty
i++;
}
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null)
convertView = View.inflate(context, layout, null);
final int pos = position;
View row = convertView;
c.moveToPosition(position);
TextView name = (TextView) row.findViewById(R.id.ListItem1);
EditText qty = (EditText) row.findViewById(R.id.qty);
qty.setOnFocusChangeListener(new View.OnFocusChangeListener() { // Set so EditText will be saved to array when you leave it
#Override
public void onFocusChange(View v, boolean hasFocus) {
if (!hasFocus) {
LinearLayout parent = (LinearLayout) v.getParent();
EditText qtyTemp = (EditText) parent.findViewById(R.id.qty); // Get a reference to EditText (you could probaly use v here)
quantity[pos] = qtyTemp.getText().toString(); // Save contents of EditText to array
}
}
});
name.setText(c.getString(1));
unit.setText(c.getString(3));
qty.setText(quantity[position]);
return (row);
}
}
Then I have a button outside the array that processes it back into my database like this:
commit.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
int i = 0;
itemCursor.moveToFirst();
while (itemCursor.isAfterLast() == false) {
if (CursorAdapter_EditText.quantity[i].equals("")) {
CursorAdapter_EditText.quantity[i] = "0";
}
;
int tempQty = Integer
.parseInt(CursorAdapter_EditText.quantity[i]);
if (tempQty != 0) {
mDbHelper.createListItem(listId, itemCursor
.getInt(itemCursor
.getColumnIndex(GroceryDB.ITEM_ROWID)),
tempQty, 0);
}
i++;
itemCursor.moveToNext();
}
}
});
I dealt with exactly the same problem by doing the following:
Remove android:descendantFocusability="beforeDescendants" from xml with ListView, android:windowSoftInputMode="adjustPan" from AndroidManifest - they ain't help.
Subclassed EditText
public class TrickyEditText extends EditText {
private boolean mFocused = false;
private boolean mTouched = false;
public TrickyEditText(Context context) {
super(context);
}
public TrickyEditText(Context context, AttributeSet attrs) {
super(context, attrs);
}
public TrickyEditText(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
#TargetApi(Build.VERSION_CODES.LOLLIPOP)
public TrickyEditText(Context context, AttributeSet attrs, int defStyleAttr, int style) {
super(context, attrs, defStyleAttr, style);
}
#Override
public boolean didTouchFocusSelect() {
if (mTouched && mFocused) {
return true;
} else {
return super.didTouchFocusSelect();
}
}
#Override
public boolean onTouchEvent(MotionEvent event) {
mTouched = true;
return super.onTouchEvent(event);
}
#Override
protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
mFocused = focused;
if (!focused) {
mTouched = false;
}
super.onFocusChanged(focused, direction, previouslyFocusedRect);
}
}
Adapter code
public class TrickyAdapter extends ArrayAdapter {
.............
#Override
public View getView(int childPosition, View convertView, final ViewGroup parent) {
.........
TrickyEditText et = ..... //initialize edittext
et.setOnFocusChangeListener(new OnFocusChangeListener() {
#Override
public void onFocusChange(final View v, boolean hasFocus) {
if (hasFocus) {
v.post(new Runnable() {
#Override
public void run() {
((EditText)v).selectAll();
}
});
}
}
});
.........
}
}
Although it's working pretty well, it's not the code I'm proud of... If somebody knows a prettier solution, please tell me!
On the getView method of your adapter, get your EditView (in this code, edittxt) and do:
edittxt.post(new Runnable() {
public void run() {
edittxt.requestFocusFromTouch();
edittxt.selectAll();
InputMethodManager lManager = (InputMethodManager)context.getSystemService(Context.INPUT_METHOD_SERVICE);
lManager.showSoftInput(edittxt, 0);
}
});
What I can say about what I asked is that trying to select all text of the listview edittexts don't work properly.
So instead of select the text, I show a dialog where the user selects the number or whatever.
Not sure if you are still looking for a solution, but I found a way to do it. Add a focus change listener to the edittext in the getView method of your adapter and select all text when focus is received.
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
// blah blah blah
EditText edit = (EditText) view.findViewById(R.id.editTextId);
edit.setOnFocusChangeListener(new OnFocusChangeListener() {
#Override
public void onFocusChange(View view, boolean hasFocus) {
if (hasFocus)
((EditText) view).selectAll();
}
});
return view;
}
I had set windowSoftInputMode to adjustPan for the activity, although I don't think it has any bearing on this matter.
I have tested this on Android 2.3 and 4 and it works.

Coding around issues with a functional ListView inside a ScrollView

I have a custom configuration page in my app which just so happens to contain a ListView which you can select/deselect, edit, add to and remove items from. Since the amount of configuration is so large I've had to put it all in a ScrollView
My problem is of course that you cannot have scroll functionality within a view which already has it's own scroll functionality. This means I can't have a scrolling ListView inside a ScrollView.
What I've been trying to do is find the best way of limiting the damage this does. I've seen suggestions that say "You could just create a LinearLayout which grows as you add more children". That would work find by the added effort required to plug in the selectable nature, the reordering & sorting of the list as well as the editing would be a maintanance nightmare.
I've spent the day trying to find a way of measuring the height of each ListView item. Once I can find the size of each item (not just the content but any padding and space between items) on each device I know I can simply change the height of the ListView per item added.
Unfortunately I can't seem to find a way to reliably pull back the height of a listviews child.
(The old chestnut of using a GlobalLayoutListener doesn't help me pull back the padding between items)
final TextView listLabel = (TextView) toReturn.findViewById(R.id.listLabel);
final ViewTreeObserver vto = listLabel.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
listLabel.getViewTreeObserver().removeGlobalOnLayoutListener(this);
mListItemHeight = listLabel.getHeight();
}
});
Maybe you're trying to display too many details on your page? You could split the activity in a summary with buttons that lead to multiple one-screen-long activities.
In my experience, users usually prefer an uncluttered and clear view, even if that means having to click once or twice to get to the part they want.
EDIT
Expanding ListView's are you're friend - This LinearLayout expands based on it's content. It allows Dynamic ListView's inside of ScrollView.
public class LinearListView extends LinearLayout {
private BaseAdapter mAdapter;
private Observer mObserver;
private OnItemClickListener mOnItemClickListener;
private OnItemLongClickListener mOnItemLongClickListener;
public LinearListView(Context context) {
super(context);
init();
}
public LinearListView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public LinearListView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
private void init() {
mObserver = new Observer();
}
public void setAdapter(BaseAdapter adapter) {
if (this.mAdapter != null)
this.mAdapter.unregisterDataSetObserver(mObserver);
this.mAdapter = adapter;
adapter.registerDataSetObserver(mObserver);
mObserver.onChanged();
}
public void setOnItemClickListener(OnItemClickListener listener) {
mOnItemClickListener = listener;
}
public void setOnItemLongClickListener(OnItemLongClickListener listener) {
mOnItemLongClickListener = listener;
}
private int mListSelector = R.drawable.selector_list;
public void setListSelector(int resid) {
mListSelector = resid;
}
private class Observer extends DataSetObserver {
public Observer(){}
#Override
public void onChanged() {
List<View> oldViews = new ArrayList<View>(getChildCount());
for (int i = 0; i < getChildCount(); i++)
oldViews.add(getChildAt(i));
Iterator<View> iter = oldViews.iterator();
removeAllViews();
for (int i = 0; i < mAdapter.getCount(); i++) {
final int index = i;
View convertView = iter.hasNext() ? iter.next() : null;
View toAdd = mAdapter.getView(i, convertView, LinearListView.this);
toAdd.setBackgroundResource(mListSelector);
toAdd.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if(mOnItemClickListener != null) {
mOnItemClickListener.onItemClick(null, v, index, index);
}
}
});
toAdd.setOnLongClickListener(new OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
if(mOnItemLongClickListener != null) {
mOnItemLongClickListener.onItemLongClick(null, v, index, index);
}
return true;
}
});
LinearListView.this.addView(toAdd, new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
}
super.onChanged();
}
#Override
public void onInvalidated() {
removeAllViews();
super.onInvalidated();
}
}
}

Get information about AutocompleteTextView from resulting AutoCompleteTextView$DropDownListView

I'm using 3 AutocompleteTextViews to suggest entries from a database.
I subclassed AutocompleteTextView to handle setting the default text to null when clicked and setting back to the default instructions if moved away and nothing is entered.
I was using a SimpleCursorAdapter to bind to the view, but I discovered that there was no way I could get the id of the AutocompleteTextView from an OnItemClickListener, which I needed to put additional information from the selected row in a variable depending on which AutocompleteTextView it was from. All I could access was the AutoCompleteTextView$DropDownListView, which is an undocumented inner class that appears to offer no real functionality. Neither was there a way to go up the view hierarchy to get the original AutocompleteTextView.
So I subclassed SimpleCursorAdapter and added an int to the constructor to identify which AutocompleteTextView the adapter was from, and I was able to access this from the view passed into OnItemClick(). So, although my solution works fine, I wonder if it is possible to get the id of an AutocompleteTextView from its DropDownListView?
I am also using another database query which gets the id from the OnItemClick and then looks up the data for that item, because I couldn't find a way of converting more than one column to a string. Should I be using CursorAdapter for this, to save initiating another query? Oh, and another thing, do I need a database cursor initially (all_cursor) when all I'm doing is filtering on it to get a new cursor? Seems like overkill.
Activity
....
dbse.openDataBase();
Cursor all_Cursor = dbse.autocomplete_query();
startManagingCursor(all_Cursor);
String[] from_all = new String[]{DbAdapter.KEY_NAME};
int[] to_all = new int[] {android.R.id.text1};
from_adapt = new AutocompleteAdapter(FROM_DBADAPTER, this,android.R.layout.simple_dropdown_item_1line, all_Cursor, from_all, to_all);
from_adapt.setStringConversionColumn(1);
from_adapt.setFilterQueryProvider(this);
to_adapt = new AutocompleteAdapter(TO_DBADAPTER, this,android.R.layout.simple_dropdown_item_1line, all_Cursor, from_all, to_all);
to_adapt.setStringConversionColumn(1);
to_adapt.setFilterQueryProvider(this);
from_auto_complete = (Autocomplete) findViewById(R.id.entry_from);
from_auto_complete.setAdapter(from_adapt);
from_auto_complete.setOnItemClickListener(this);
to_auto_complete = (Autocomplete) findViewById(R.id.entry_to);
to_auto_complete.setAdapter(to_adapt);
to_auto_complete.setOnItemClickListener(this);
public void onItemClick (AdapterView<?> parent, View view, int position, long id) {
Cursor selected_row_cursor = dbse.data_from_id(id);
selected_row_cursor.moveToFirst();
String lat = selected_row_cursor.getString(1);
String lon = selected_row_cursor.getString(2);
int source = ((AutocompleteAdapter) parent.getAdapter()).getSource();
Autocomplete class:
public class Autocomplete extends AutoCompleteTextView implements OnTouchListener,OnFocusChangeListener{
String textcontent;
Context mycontext = null;
int viewid = this.getId();
public Autocomplete(Context context, AttributeSet attrs) {
super(context, attrs);
textcontent = this.getText().toString();
mycontext = context;
this.setOnFocusChangeListener(this);
this.setOnTouchListener(this);
}
public boolean onTouch(View v, MotionEvent event) {
if (textcontent.equals(mycontext.getString(R.string.from_textbox)) |
textcontent.equals(mycontext.getString(R.string.to_textbox)) |
textcontent.equals(mycontext.getString(R.string.via_textbox))) {
this.setText("");
}
return false;
}
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus == false) {
int a = this.getText().length();
if (a == 0){
if (viewid == R.id.entry_from) {this.setText(R.string.from_textbox);}
if (viewid == R.id.entry_to) {this.setText(R.string.to_textbox);}
if (viewid == R.id.entry_via) {this.setText(R.string.via_textbox);}
}
}
}
}
Adapter:
public class AutocompleteAdapter extends SimpleCursorAdapter {
int source;
public AutocompleteAdapter(int query_source, Context context, int layout, Cursor c,
String[] from, int[] to) {
super(context, layout, c, from, to);
source = query_source;
}
public int getSource() {
return source;
}
}
sorry that's a lot of code! Thanks for your help.
Stephen
Instead of using this as the listener, create a new listener class and give it your autocomplete textview:
public class MyActivity extends Activity {
// .... somewhere
from_auto_complete.setOnItemClickListener(new MyClickListener(from_auto_complete));
private class MyClickListener implements OnClickListener {
AutoCompleteTextView autoComplete;
MyClickListener(AutoCompleteTextView actv) {
autoComplete = actv;
}
// ... handle clicks
}
}

Android: Binding data from a database to a CheckBox in a ListView?

I'm trying to bind data from my SQLiteDatabase to a ListView. I'm currently using a SimpleCursorAdapter to fill in my ListView. Unfortunately this doesn't seem to work with setting a CheckBox's checked attribute.
This is how I do it now; instead of changing the CheckBox's checked status the adapter is filling in the value to the text argument, so the value is displayed right of the CheckBox as text.
Java:
setListAdapter( new SimpleCursorAdapter( this,
R.layout.mylist,
data,
new String[] { Datenbank.DB_STATE, Datenbank.DB_NAME },
new int[] { R.id.list_checkbox, R.id.list_text }
) );
mylist.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout android:id="#+id/LinearLayout01"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
xmlns:android="http://schemas.android.com/apk/res/android"
>
<CheckBox android:text=""
android:id="#+id/list_checkbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="false"
></CheckBox>
<TextView android:text=""
android:id="#+id/list_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
></TextView>
</LinearLayout>
Edit: The field in the database is of course of type boolean and I've also tried to assign an id to the checked field to fill the value in.
You could set a custom SimpleCursorAdapter.ViewBinder:
SimpleCursorAdapter cursorAdapter = new SimpleCursorAdapter(/* ur stuff */);
cursorAdapter.setViewBinder(new SimpleCursorAdapter.ViewBinder() {
public boolean setViewValue(View view, Cursor cursor, int columnIndex) {
if(columnIndex == 1) {
CheckBox cb = (CheckBox) view;
cb.setChecked(cursor.getInt(1) > 0);
return true;
}
return false;
}
});
The setViewValue method is invoked for every column you specify in the SimpleCursorAdapter constructor and gives you a good place to manipulate some (or all) of the views.
I'm not sure how you would do this aside from creating a custom Adapter that overrode newView/bindView or getView, depending on what you override (ResourceCursorAdapter is a good one).
Ok, so here's an example. I didn't test to see if it would compile because I'm at work, but this should definitely point you in the right direction:
public class MyActivity extends ListActivity {
MyAdapter mListAdapter;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Cursor myCur = null;
myCur = do_stuff_here_to_obtain_a_cursor_of_query_results();
mListAdapter = new MyAdapter(MyActivity.this, myCur);
setListAdapter(mListAdapter);
}
private class MyAdapter extends ResourceCursorAdapter {
public MyAdapter(Context context, Cursor cur) {
super(context, R.layout.mylist, cur);
}
#Override
public View newView(Context context, Cursor cur, ViewGroup parent) {
LayoutInflater li = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
return li.inflate(R.layout.mylist, parent, false);
}
#Override
public void bindView(View view, Context context, Cursor cur) {
TextView tvListText = (TextView)view.findViewById(R.id.list_text);
CheckBox cbListCheck = (CheckBox)view.findViewById(R.id.list_checkbox);
tvListText.setText(cur.getString(cur.getColumnIndex(Datenbank.DB_NAME)));
cbListCheck.setChecked((cur.getInt(cur.getColumnIndex(Datenbank.DB_STATE))==0? false:true))));
}
}
}
You can solve that problem by creating a custom CheckBox widget like so:
package com.example.CustomCheckBox;
public class CustomCheckBox extends CheckBox {
public CustomCheckBox(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public CustomCheckBox(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CustomCheckBox(Context context) {
super(context);
}
protected void onTextChanged(CharSequence text, int start, int before, int after) {
if (text.toString().compareTo("") != 0) {
setChecked(text.toString().compareTo("1") == 0 ? true : false);
setText("");
}
}
}
The onTextChanged function will be called when the ListView binds the data to the CheckBox (ie. Adding either "0" or "1"). This will catch that change and add in your boolean processing. The 1st "if" statement is needed so as to not create infinite recursion.
Then provide your custom class in to the layout file as such:
<com.example.CustomCheckBox
android:id="#+id/rowCheckBox"
android:layout_height="fill_parent"
android:layout_width="wrap_content" />
That should do it!

Categories

Resources