如何刷新GridView中的子视图?

时间:2014-01-09 20:13:06

标签: android gridview

我有GridView显示了一些TextView,我们绘制了视图,以便 ONE 被标记为已选中。问题是,当用户交互更改我逻辑中的选定项目时,我想更新所涉及的视图,即显示上一个选定项目的视图显示当前所选项目的视图。 (当然,在我的实际问题中,网格中的子视图更复杂,更新过程可能涉及一些计算,加载资源,访问数据库等。)

直到现在我正在使用BaseAdapter.notifyDataSetChangedGridView.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);

2 个答案:

答案 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威胁的操作,并且可以在完成后更新适配器。

例如,您可以让适配器具有表示每个视图的对象列表。然后,要更新适配器,您只需要为其提供一个新的已更改对象列表,并通知它数据已更改。