如何动态更改适配器布局?

时间:2014-08-13 10:16:16

标签: android adapter

我有一个自定义Adapter,其中我希望行布局根据方向进行更改。

我有一个函数setOrientation,我在其中修改布局并调用notifyDataSetChanged(),希望一切都会被重置。

不幸的是,似乎不是因为即使在notifyDataSetChanged()之后,convertView的第一次调用中的getView()也不为空,因此布局不会更改。

有没有办法重置此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;
    }
}

3 个答案:

答案 0 :(得分:3)

最快的方式: 创建TableRowsAdapter的新实例并再次设置它(使方向成为构造函数参数)。 例如:

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

}

正确方法:

当你setOrientation时,膨胀新布局并将convertView替换为

原因:notifyDatasetChanged()不知道您将替换布局,因此它只是回收视图,从而使convertView不为空。

在布局R.layout.table_row_landR.layout.table_row中,为根视图添加唯一ID

示例:

R.layout.table_row_land

ID为R.id.row_landR.layout.table_rowR.id.row_normal

根视图会变成这样:

<?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>

这是一个简单的伪实现:

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

答案 1 :(得分:1)

创建一个文件table_row.xml并放入res/layout文件夹并创建另一个名称为table_row.xml的文件,该文件与table_row_land.xml相同并放入res/layout-land

并在适配器集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);
        }
        ...
        ...
        ...

     }

答案 2 :(得分:0)

在您的布局中创建两个视图(在相同的XML中),并为第二个布局设置可见性。按照您已经完成的方式对其进行充实,并在get view方法中根据方向显示视图。

@覆盖     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;
}