当使用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();
}
}
答案 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标签用于其他用途了。