Get Item Position From Custom Adapter

Jason Crosby picture Jason Crosby · Apr 3, 2013 · Viewed 8k times · Source

Since PreferenceFragment is not available in the support library I created a ListFragment to show a list of settings to a user since I don't have a lot of settings to show. I also created a custom ArrayAdapter to customize the list items. I need to handle when a user checks one of the CheckBoxs so I can save weather or not it was checked. So if its checked then it will stay checked until the user uncheckes it. This would be much easier if there was only one setting in the list but there are 2 for now and I might need to add more. So I need to be able to determine which one was checked. I can handle the check and uncheck fine I just cant find a way to determine which one was checked.

THE CODE

Here is my list item:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >

<LinearLayout android:layout_width="match_parent" android:layout_height="match_parent"
                      android:orientation="horizontal">

<TextView android:id="@+id/pref_edit_text" android:layout_width="0dp" android:layout_height="30dp"
              android:layout_weight="5"/>
    <CheckBox android:id="@+id/pref_check_box" android:layout_width="0dp" android:layout_height="wrap_content"
              android:layout_weight="1" android:onClick="onCheckBoxClick"/>
    </LinearLayout>

<TextView android:id="@+id/pref_edit_text2" android:layout_width="match_parent"
              android:layout_height="50dp"/>

Here is getView() in my adapter:

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        //mIntCheckBoxPosition = position;
        Typeface tf = Typeface.createFromAsset(mMainActivity.getAssets(), "fonts/ArchitectsDaughter.ttf");
        LayoutInflater inflater = mMainActivity.getLayoutInflater();
        View view = inflater.inflate(mIntLayoutId, parent, false);

        TextView text = (TextView) view.findViewById(R.id.pref_edit_text);
        text.setText(mStringArrayTitle[position]);
        text.setTypeface(tf, Typeface.BOLD);

        text = (TextView) view.findViewById(R.id.pref_edit_text2);
        text.setText(mStringArraySubTitle[position]);
        text.setTypeface(tf);

        mMainActivity.setTitle("Settings");

        return view;
    }

And here is where I handle when a CheckBox is clicked which is in the ListFragment:

    public void onCheckBoxClick(View view) {
        boolean isChecked = ((CheckBox) view).isChecked();
        Editor editor = mMainActivity.getSharedPreferences(PREF_KEY_CHECK_BOX, Activity.MODE_PRIVATE).edit();

        switch (view.getId()) {
            case R.id.check_box :
                if (isChecked) {
                    editor.putBoolean(PREF_KEY_ROUNDING, true).commit();
                }
                else {
                    editor.putBoolean(PREF_KEY_ROUNDING, false).commit();
                }
                break;
            }
        }
    }

Here is what my settings look like:
enter image description here

WHAT I HAVE TRIED
1. I have tried setting a variable in the adapter to the item position and using a getter to get the position, but that only returns the position of the last item shown.
2. I have tried using some of the methods in ListFragment to get the position of the CheckBox but they always return -1.
3. I have done a lot of Googling and searching on SO but I have not been able to find a solution to get this to work.

So if anyone knows of a way I can get the position of the CheckBox or any other ways I might be able to tell which one was clicked I will be eternally grateful.

Answer

Tushar picture Tushar · Apr 3, 2013

You can use setTag to add an int to the view indicating its position, and then retreive that later using getTag. Ex:

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    ... // your other code here

    CheckBox checkbox = (CheckBox) view.findViewById(R.id.pref_check_box);
    checkbox.setTag(new Integer(position));

}

Then, in your onCheckBoxClick:

public void onCheckBoxClick(View view) {
    Integer pos;
    pos = (Integer) view.getTag();

    ... // do what you want with `pos` here

}