数据更改后,GridView不刷新视图 [英] GridView is not refreshing view after data changed

查看:186
本文介绍了数据更改后,GridView不刷新视图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



在调试器中,我可以看到 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆