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;
}
}
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