在setOnItemClickListener上更新适配器数据和notifydatachange

时间:2018-11-03 14:35:47

标签: android gridview onitemclicklistener

当使用Normal字符串数组作为gridview的数据源时,直接修改数组并调用notifydatachange是可行的,但是当数据是自定义适配器时,gridview不会更新。
我知道修改当前单元格的textview是可行的,但是当一个单元格的值更改时,我想更改两个GridView,其中两个适配器具有相同的String对象,并且根据Java中Is Java "pass-by-reference" or "pass-by-value"?对象的大量注释通过引用和两个适配器传递应该更改,但就我而言,它们都没有更改。

网格单元格自定义类

public class GridCell {
private static final String TAG = "GridCell";
private String cell_value;

public GridCell(String cell_value) {
    this.cell_value = cell_value;
}

public String getcell_value() {
    return cell_value;
}
public void setcell_value(String c) {
    this.cell_value = c;
}
}

适配器代码

public class GridCellAdapter extends ArrayAdapter<GridCell> {
public GridCellAdapter(Context context, int textViewId, ArrayList<GridCell> cells) {
    super(context, textViewId, cells);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
    // Get the data item for this position
    GridCell cell = getItem(position);
    // Check if an existing view is being reused, otherwise inflate the view
    if (convertView == null) {
        convertView = LayoutInflater.from(getContext()).inflate(R.layout.gv_item_fixedline, parent, false);
        // following code is moved out of if block AFTER Ben's answer  below. so to avoid other user might suggest same solution
        //TextView tv = (TextView) convertView.findViewById(R.id.cellval);
        //tv.setText(cell.getcell_value());
    }
    TextView tv = (TextView) convertView.findViewById(R.id.cellval);
    tv.setText(cell.getcell_value());
// save the object so that this object can be modified by setOnItemClickListener

    convertView.setTag(cell);
    return convertView;
}

@Override
public int getCount() {
    return super.getCount();
}
}

主要活动

public class MainActivity extends AppCompatActivity {

GridView gridView1;
GridView gridView2;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    // init gridview

    // Construct the data source for GridView1
    ArrayList<GridCell> arrayOfCells1 = new ArrayList<GridCell>();
    // Create the adapter to convert the array to views
    final GridCellAdapter gcAdapter1 = new GridCellAdapter(this, R.layout.gv_item_fixedline, arrayOfCells1);
    gridView1 = (GridView) findViewById(R.id.gridView1);
    gridView1.setAdapter(gcAdapter1);


    // Construct the data source for GridView2
    ArrayList<GridCell> arrayOfCells2 = new ArrayList<GridCell>();
    // Create the adapter to convert the array to views
    final GridCellAdapter gcAdapter2 = new GridCellAdapter(this, R.layout.gv_item_fixedline, arrayOfCells2);
    gridView2 = (GridView) findViewById(R.id.gridView2);
    gridView2.setAdapter(gcAdapter2);

    for (int i = 1; i <= 3; i++) {
        // both adapter now has same object reference. am I right here?
        GridCell tmp = new GridCell("U");
        gcAdapter1.add(tmp);
        gcAdapter2.add(tmp);
    }


    gridView1.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            // this object is shared by both adapter 
            GridCell cell = (GridCell) view.getTag();
            Log.d(TAG, "onItemClick: " + cell.getcell_value());
            cell.setcell_value("X");
            Log.d(TAG, "onItemClick: modified :" + cell.getcell_value());
            Toast.makeText(getApplicationContext(), Integer.toString(position), Toast.LENGTH_SHORT).show();
        }
    });

    gcAdapter1.notifyDataSetChanged();
    gcAdapter2.notifyDataSetChanged();

}


}

1 个答案:

答案 0 :(得分:0)

在您的getView()方法中,您具有以下代码:

if (convertView == null) {
    convertView = LayoutInflater.from(getContext()).inflate(R.layout.gv_item_fixedline, parent, false);
    TextView tv = (TextView) convertView.findViewById(R.id.cellval);
    tv.setText(cell.getcell_value());
}

您应将setText()调用移到if块之外:

if (convertView == null) {
    convertView = LayoutInflater.from(getContext()).inflate(R.layout.gv_item_fixedline, parent, false);
}

TextView tv = (TextView) convertView.findViewById(R.id.cellval);
tv.setText(cell.getcell_value());

否则,当数据更改时(假设视图已回收),文本将不会更新。

请注意,调用findViewById()有点昂贵,这就是为什么建议您使用“视图持有者模式”,但这里已经将view标签用于其他用途了。