Search code examples
androidandroid-layoutandroid-arrayadapterandroid-viewandroid-custom-view

how to use Tag instead of R.id. in constructor of a custom ArrayAdapter?


In my Android project, I need to find views in my Activity by their tags rather than their IDs. (If you ask me why I don't simply use findViewById, It's not my prefer, and is complicated to describe, but currently I can't rely on R.id. constants!) So far, to find views in my code, I have managed to use this successfully:

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.index);
    mainViewGroup = (ViewGroup)getWindow().getDecorView();
    TextView indexCaption = (TextView) mainViewGroup.findViewWithTag("index_caption");
    // Now I have my TextView and can use it without problem
}

But now, the problem is my custom ArrayAdapter in the same activity:

    class IconicAdapter extends ArrayAdapter<String> {
    IconicAdapter() {
                    // How I can use Tag instead of R.layout.index_row_caption here?!!!
        super(IndexActivity.this, R.layout.index_row, R.id.index_row_caption, arrayList);
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View row = super.getView(position, convertView, parent);
                    // Some customizations...
        return (row);
    }
}

and index_row.xml for that IconicAdapter:

android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="@drawable/content_bg" >

<TextView
    android:id="@+id/index_row_caption"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_centerVertical="true"
    android:layout_toLeftOf="@+id/index_row_icon"
    android:layout_toRightOf="@+id/index_row_search"
    android:gravity="right"
    android:tag="index_row_caption"
    android:textAppearance="?android:attr/textAppearanceLarge" />

<ImageView
    android:id="@+id/index_row_icon"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentRight="true"
    android:tag="index_row_icon" />

<ImageView
    android:id="@+id/index_row_search"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentLeft="true"
    android:layout_centerVertical="true"
    android:src="@drawable/index_row_search"
    android:tag="index_row_search" />

How I can avoid using R.id.index_row_caption in the constructor and replace it with something related to its tag?

EDIT: At last, I have ended up to this code and it worked great: (credits and bounty goes for pawelzieba who helped me on this)

    class IconicAdapter extends ArrayAdapter<String> {
    IconicAdapter() {
        super(IndexActivity.this, R.layout.index_row, 0, arrayList);
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        View view;
        if (convertView == null) {
            LayoutInflater mInflater = IndexActivity.this.getLayoutInflater();
            view = mInflater.inflate(R.layout.index_row, parent, false);
        } else {
            view = convertView;
        }

        //find views
        TextView text = (TextView) view.findViewWithTag("index_row_caption");

        //fill views with data
        text.setText(arrayList.get(position));          

        return view;
    }
}

Solution

  • Extend ArrayAdapter and override getView() method.

    public View getView(int position, View convertView, ViewGroup parent) {
        View view;
    
        if (convertView == null) {
            view = mInflater.inflate(R.layout.index_row, parent, false);
        } else {
            view = convertView;
        }
    
        //find views
        TextView text = (TextView) view.findViewWithTag("index_row_caption");
    
        //fill views with data
        //example:
        T item = getItem(position);
        text.setText(item.toString());
    
    
        return view;
    }
    

    Then row resource id passed to constructor is unused.

    To get better performance use View Holder Pattern to call findViewWithTag only once on create row's view: http://www.vogella.com/articles/AndroidListView/article.html#adapterperformance_hoder