2014-01-09 32 views
0

我有显示一些TextViewGridView,视图画出以便ONE作为选择标记。问题是,当用户交互我的逻辑改变所选择的项目我想更新的意见参与,即视图显示先前选定的项目显示当前选择的项目的看法。 (当然,在我真正的问题中,网格中的子视图更复杂,更新过程可能涉及一些计算,加载资源,访问数据库等)。如何刷新GridView中的子视图?

直到现在,我正在使用BaseAdapter.notifyDataSetChangedGridView.invalidateViews和都做的工作,但也更新所有GridView的可见子视图,但我想要更新只是TWO其中意见。

我该怎么做?如何获得更新过程的两个视图?

注:我现在面临这个问题,ListView S还,但我觉得可能会有相同的解决方案。

示例代码:

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); 

回答

1

重新创建视图的所有时间:

到底是什么更新的看法的问题时getView叫?如果你什么都不做,但改变TextView的文字,我可以看到没有问题。

如果您打算做更多的事情,你需要改变Adapter是你的看法。见下文。

长时间运行操作和适配器

你不应该在适配器本身做任何长期运行的操作。而不是在getView中。

你应该开始考虑Adapter S作为......嗯适配器。它们将您拥有的数据调整到当前的UI环境。

因此,从数据库或类似的东西中获取数据不是适配器的工作。适配器应该提供数据并简单地将其调整为视图。

用于向适配器提供数据考虑使用AsyncTask。它执行远离UI威胁的操作,并且可以在完成时更新适配器。

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

+0

还是这个问题,我想只是更新两个视图,不是全部,如果没有简单的方法,我可以没有它然后生活。避免我在更新过程中做的事情,这只是一个例子。关键是为什么更新所有可见的视图,如果我只关心TWO。 –

+0

你怎么知道他们正在更新?你能看到不改变文本的视图有什么不同吗?如果不是那么你为什么在意?也许Android足够智能,不会更新屏幕上的像素,如果他们没有改变。 – doorstuck

+0

首先,我需要更新先前选择的项目的视图,然后是新选择的项目的视图,我知道我只需要视图的项目的位置或使用像'GridView.recreateThisView(int)' –

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!"); 

    } 
} 
+0

如果我需要更新的视图不可见,该怎么办?此外,我如何识别需要的两个视图?如果它不可见,我正在寻找类似于'GridView.getViewAtPosition(int)' –

+1

的东西,这意味着它还不存在。因此,您可以更新适配器的getView方法中的那些。这是为那些已经创建的。 – ayorhan