Reputation: 37484
I have a custom Adapter
in which I'd like the row layout to change according to the orientation.
I have a function setOrientation
in which I modify the layout and call notifyDataSetChanged()
, hoping that everything would be reset.
Unfortunately, it seems that it is not because even after notifyDataSetChanged()
, the convertView
in the first call of getView()
is not null, so the layout is not changed.
Is there any way to reset this convertView
?
public class TableRowsAdapter extends BaseAdapter {
private LayoutInflater layoutInflater;
private int layout;
private TableRow[] items;
private class ViewHolder {
/* some stuff */
}
public TableRowsAdapter(Context context, TableRow[] tableRowList)
{
super();
this.items = tableRowList;
this.layoutInflater = (LayoutInflater) context.getSystemService( Context.LAYOUT_INFLATER_SERVICE );
/* Set default layout to portrait */
layout = R.layout.table_row;
}
public void setOrientation(int orientation){
if(orientation== Configuration.ORIENTATION_LANDSCAPE){
layout = R.layout.table_row_land;
}
else{
layout = R.layout.table_row;
}
notifyDataSetChanged();
}
public int getCount()
{
return items.length;
}
public TableRow getItem(int position)
{
return items[position];
}
public long getItemId(int position)
{
return position;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder;
View v = convertView;
if (v == null) {
v = layoutInflater.inflate(layout, parent, false);
holder = new ViewHolder();
/* some stuff */
v.setTag(holder);
} else {
holder = (ViewHolder) v.getTag();
}
TableRow item = getItem(position);
/* some stuff */
return v;
}
}
Upvotes: 3
Views: 4973
Reputation: 2215
Create one file table_row.xml
and put res/layout
folder and create another file with same name table_row.xml
which is same as table_row_land.xml
and put in to res/layout-land
.
and in adapter set table_row.xml
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder;
View v = convertView;
if (v == null) {
v = layoutInflater.inflate(R.layout.table_row, parent, false);
}
...
...
...
}
Upvotes: 1
Reputation: 8972
Fastest way:
create a new instance of TableRowsAdapter
and set it again(make the orientation a constructor parameter).
Example:
public TableRowsAdapter(Context context, TableRow[] tableRowList, int orientation)
{
super();
this.items = tableRowList;
this.layoutInflater = (LayoutInflater) context.getSystemService( Context.LAYOUT_INFLATER_SERVICE );
if(orientation== Configuration.ORIENTATION_LANDSCAPE){
layout = R.layout.table_row_land;
}
else{
layout = R.layout.table_row;
}
}
The proper way:
when you setOrientation
, inflate the new layout and replace convertView with that
Reason: notifyDatasetChanged()
does not know that you'll replace the layout, so it simply recycles the view thus making convertView
not null.
In layout R.layout.table_row_land
and R.layout.table_row
, add an unique id for the root view,
Example:
id for R.layout.table_row_land
is R.id.row_land
and R.layout.table_row
is R.id.row_normal
The root view would become something like this:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/row_normal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<!-- the rest of the layout -->
</LinearLayout>
And here's a simple pseudo implementation:
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder;
View v = convertView;
// check if convertView needs a new layout here
if (v == null || (v.getId() == R.id.row_normal && layout == R.layout.table_row_land)) {
v = layoutInflater.inflate(layout, parent, false);
holder = new ViewHolder();
/* some stuff */
v.setTag(holder);
} else {
holder = (ViewHolder) v.getTag();
}
TableRow item = getItem(position);
/* some stuff */
return v;
}
Upvotes: 4
Reputation: 1805
Make Both of Two Views in your layout(in same XML) and set visibility gone for second layout.inflate it as you have already done, and in get view method make visibility of view according to orientation.
@Override public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder;
View v = convertView;
if (v == null) {
v = layoutInflater.inflate(layout, parent, false);
holder = new ViewHolder();
/* some stuff */
v.setTag(holder);
} else {
holder = (ViewHolder) v.getTag();
}
TableRow item = getItem(position);
/* some stuff */
if(portrait) {
// then visiblity of first View or View Group set Visible and
// visiblity of second View or View Group set Gone
} else {
// then visiblity of first View or View Group set GONE and
// visiblity of second View or View Group set Visible.
}
return v;
}
Upvotes: 0