GridView is not refreshing view after data changed

妖精的绣舞 提交于 2020-01-04 14:09:01

问题


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

回答1:


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.




回答2:


  1. From your posted code, there's no need to override the getCount() and getItem() methods. Just the getView() will work fine.
  2. You cannot update the external Tile list (in the activity) and expect the adapter to update. This is bad for many reason. Basically it boils down to your external list is not guaranteed to be the same list reference in the adapter. Can read more about it here: ArrayAdapter Constructor - Issues
  3. If you need to add items to the gridAdapter then use it's addAll() method directly. If you need to clear items from the adapter...use it's clear() method.


来源:https://stackoverflow.com/questions/24874177/gridview-is-not-refreshing-view-after-data-changed

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!