我有GridView
显示了一些TextView
,我们绘制了视图,以便 ONE 被标记为已选中。问题是,当用户交互更改我逻辑中的选定项目时,我想更新所涉及的视图,即显示上一个选定项目的视图和显示当前所选项目的视图。 (当然,在我的实际问题中,网格中的子视图更复杂,更新过程可能涉及一些计算,加载资源,访问数据库等。)
直到现在我正在使用BaseAdapter.notifyDataSetChanged
或GridView.invalidateViews
并且两者都做了工作,但也更新了所有 GridView
的可见子视图但是我想要更新其中的两个视图。
我该怎么做?如何获得更新过程的两个视图?
注意:我也遇到ListView
的问题,但我想也许它会有相同的解决方案。
示例代码:
public class MainActivity extends Activity {
private int selectedPos = 36;
private class MyAdapter extends BaseAdapter {
@Override
public int getCount() {
return 100;
}
@Override
public Object getItem(int position) {
return position;
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
TextView tv;
if(convertView==null) {
tv = new TextView(MainActivity.this);
} else {
tv = (TextView) convertView;
}
Log.d("Updating -----", String.valueOf(position));
if(position==selectedPos)
tv.setText("Item ".toUpperCase() + String.valueOf(position));
else
tv.setText("Item " + String.valueOf(position));
return tv;
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final GridView gv = (GridView) findViewById(R.id.gridView1);
gv.setAdapter(new MyAdapter());
gv.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
selectedPos = position;
//gv.invalidateViews();
((MyAdapter)gv.getAdapter()).notifyDataSetChanged();
}
});
}
}
我正在寻找的是(某种伪代码):
updateThisViewAsNotSelected(selectedPos);
gv.redrawThisView(selectedPos);
selectedPos = position;
updateThisViewAsSelected(selectedPos);
gv.redrawThisView(selectedPos);
答案 0 :(得分:1)
您需要遍历列表或网格视图中的可见子项以实现此目的。例如,如果您想通过网格视图实现该目标:
for(int k = gridView.getFirstVisiblePosition(); k <= gridView.getLastVisiblePosition(); k++) {
View view = gridView.getChildAt(k);
// you can update the view here
}
如果你想从特定的位置找个孩子:
int firstVisiblePosition = gridView.getFirstVisiblePosition();
for (int k = 0; k < gridView.getChildCount(); k++ ) {
int current = firstVisiblePosition + k;
if (current == updateThisPosition) {
View child = gridView.getChildAt(i);
// Update the view
TextView anything = (TextView) child.findViewById(R.id.anything_text);
anything.setText("updated!");
}
}
答案 1 :(得分:1)
始终重新创建视图:
调用getView
时更新视图的确切问题是什么?如果您不做任何事情,只需更改TextView
的文字,我就看不出任何问题。
如果您打算再做一些事情,则需要更改Adapter
的观点。见下文。
长时间运行的操作和适配器
您永远不应该在适配器本身中执行任何长时间运行的操作。而不是getView。
你应该开始考虑将Adapter
作为......适配器。他们将您拥有的数据调整为当前的UI上下文。
因此,从数据库或类似的东西获取数据不是适配器的工作。适配器应该输入数据并简单地将其调整为视图。
为了向适配器提供数据,请考虑使用AsyncTask
。它执行远离UI威胁的操作,并且可以在完成后更新适配器。
例如,您可以让适配器具有表示每个视图的对象列表。然后,要更新适配器,您只需要为其提供一个新的已更改对象列表,并通知它数据已更改。