数据更改后,GridView不刷新视图 [英] GridView is not refreshing view after data changed
问题描述
在调试器中,我可以看到 getView
在 notifyDataSetChanged
后没有被调用。
我不知道为什么......我可以看到底层数据正在改变,但没有任何事情发生在GridView上。
我尝试了几种解决方案没有工作,所以我发布我认为应该是正确的(即使它显然不是...)
这是我的主要活动
私有GridView网格;
私人TileGridAdapter gridAdapter;
private ArrayList< Tile>列表;
私人GameManager gameManager;
@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
gameManager = new GameManager(4);
list =(ArrayList< Tile>)gameManager.getTiles();
grid =(GridView)findViewById(R.id.grid);
gridAdapter = new TileGridAdapter(this,list);
grid.setAdapter(gridAdapter);
grid.setOnTouchListener(new OnSwipeTouchListener(MainActivity.this){
public void onSwipeTop(){
gameManager.move(Direction.Up);
list.clear ();
list.addAll(gameManager.getTiles());
gridAdapter.notifyDataSetChanged();
}
$ b $ public void onSwipeRight(){
Toast.makeText(MainActivity.this,right,Toast.LENGTH_SHORT).show();
}
public void onSwipeLeft(){
Toast.makeText(MainActivity这个left,Toast.LENGTH_SHORT).show();
}
public void onSwipeBottom(){
Toast.makeText(MainActivity.this,bottom ,Toast.LENGTH_SHORT).show();
}
});
自定义适配器
public class TileGridAdapter extends ArrayAdapter< Tile> {
上下文上下文;
ArrayList< Tile>瓷砖;
public TileGridAdapter(Context context,ArrayList< Tile> tile){
super(context,R.layout.cell_layout,tiles);
this.context = context;
this.tiles = tiles;
}
@Override
public int getCount(){
return tiles.size();
}
@Override
public Tile getItem(int position){
return tiles.get(position);
}
@Override
public View getView(int position,View convertView,ViewGroup parent){
View view = convertView;
if(view == null){
LayoutInflater inflater =((Activity)context).getLayoutInflater();
view = inflater.inflate(R.layout.cell_layout,parent,false);
Tile tile = tiles.get(position);
TextView tv =(TextView)view.findViewById(R.id.cell_view);
if(tile!= null){
tv.setText(String.valueOf(tile.getValue()));
}
}
返回视图;
就我所见,问题在于如果convertview为null,getView只会膨胀并填充视图。根据我的经验,convertview在列表初始加载时仅为null,从此视图重用。您应该检查以确定视图是否存在并且具有适当的数据。如果它有错误的数据,那么填充新的数据(或者只是总是填充新的数据。)
这就是为什么 viewholder pattern 可能会有所帮助。
例如:
if(view == null || ((Holder)view.getTag())。getItem()。equals(getItem()))
{
...
你应该把这个检查分成多行,但这就是主意。
或
将除通货膨胀以外的所有内容移至if语句的外部。
I have a GridView with a custom adapter that wont refresh.
In the debugger I can see that getView
is not being called after notifyDataSetChanged
.
I have no idea why... I can see that the underlying data is being changed but nothing is happening to the GridView.
I tried several solutions which didn't work, so I'm posting what I think should be the right one (even though it clearly isn't...)
This is in my main activity
private GridView grid;
private TileGridAdapter gridAdapter;
private ArrayList<Tile> list;
private GameManager gameManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
gameManager = new GameManager(4);
list = (ArrayList<Tile>) gameManager.getTiles();
grid = (GridView) findViewById(R.id.grid);
gridAdapter = new TileGridAdapter(this, list);
grid.setAdapter(gridAdapter);
grid.setOnTouchListener(new OnSwipeTouchListener(MainActivity.this) {
public void onSwipeTop() {
gameManager.move(Direction.Up);
list.clear();
list.addAll(gameManager.getTiles());
gridAdapter.notifyDataSetChanged();
}
public void onSwipeRight() {
Toast.makeText(MainActivity.this, "right", Toast.LENGTH_SHORT).show();
}
public void onSwipeLeft() {
Toast.makeText(MainActivity.this, "left", Toast.LENGTH_SHORT).show();
}
public void onSwipeBottom() {
Toast.makeText(MainActivity.this, "bottom", Toast.LENGTH_SHORT).show();
}
});
}
And the custom adapter
public class TileGridAdapter extends ArrayAdapter<Tile> {
Context context;
ArrayList<Tile> tiles;
public TileGridAdapter(Context context, ArrayList<Tile> tiles) {
super(context, R.layout.cell_layout, tiles);
this.context = context;
this.tiles = tiles;
}
@Override
public int getCount() {
return tiles.size();
}
@Override
public Tile getItem(int position) {
return tiles.get(position);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
if (view == null) {
LayoutInflater inflater = ((Activity) context).getLayoutInflater();
view = inflater.inflate(R.layout.cell_layout, parent, false);
Tile tile = tiles.get(position);
TextView tv = (TextView) view.findViewById(R.id.cell_view);
if (tile != null) {
tv.setText(String.valueOf(tile.getValue()));
}
}
return view;
}
}
As far as I can see, the problem is your getView is only inflating and populating a view if the convertview is null. In my experience, the convertview is only null on the initial loading of the list and from then on the views are reused. You should check to see if the view both exists and has the proper data. If it has the wrong data then populate with new data (or just always populate with new data.)
This is why the viewholder pattern can be helpful.
For example:
if( view == null || ((Holder)view.getTag()).getItem().equals(getItem()) )
{
...
You should probably break up that check into multiple lines, but that's the idea.
OR
Move everything except the inflation to the outside of the if statement.
这篇关于数据更改后,GridView不刷新视图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!