【发布时间】:2018-11-03 14:35:47
【问题描述】:
当使用普通字符串数组作为gridview的数据源时,只需直接修改数组并调用notifydatachange即可,但是当数据是自定义适配器时,gridview不会更新。
我知道修改当前单元格的 textview 是可行的,但是当一个单元格的值发生更改时,我想更改两个 GridView,其中两个适配器具有相同的 String 对象,并且根据 java 中 Is Java "pass-by-reference" or "pass-by-value"? 对象中的巨大 cmets 通过引用传递,并且两个适配器都应该是改变了,但就我而言,它们都没有改变。
网格单元自定义类
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();
}
}
【问题讨论】:
-
添加你关于
setOnItemClickListener的代码,顺便说一下,我猜你的适配器的方法getCount不应该是super.getCount() -
setOnItemClickListener 已在 gridview1 上注册,因为我需要在两个 gridview 上调用 notifyDataSetChanged。至于 super.getcount() 我基于 github.com/codepath/android_guides/wiki/… 的 Using a Custom ArrayAdapter 方法进行编码,其中 User 数组未在 Adapter 类中声明为私有变量,我认为这是可选的,只需用默认定义的 getCount 覆盖。跨度>
-
暂时使用stackoverflow.com/a/20053133/538212 的解决方案我认为Ben 下面的回答应该有效,但它没有。这是一个错误还是与 GridView 适配器的范围相关(在 MainActivity 中全局声明并可访问)?
标签: android gridview onitemclicklistener