Search code examples
androidgridviewandroid-viewbaseadapter

How can I fix a non-properly loading custom Adapter when the item is out of screen


I'm building a view with a custom ButtonAdapter, which loads a StringArray and puts out a GridView with Buttons. Until the buttons are out of the Screen everything loads fine, but the last few Buttons which I only can see when I scroll down, are wrong.

public class ButtonAdapter extends BaseAdapter {
    private Context context;
    private final String[] mobileValues;

    public ButtonAdapter(Context context, String[] mobileValues) {
        this.context = context;
        this.mobileValues = mobileValues;
    }

    public View getView(int position, View convertView, ViewGroup parent) {

        LayoutInflater inflater = (LayoutInflater) context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        View gridView;

        if (convertView == null) {

            gridView = new View(context);

            gridView = inflater.inflate(R.layout.button, null);

            Button button = (Button) gridView
                    .findViewById(R.id.button);
            button.setText(mobileValues[position]);
            Log.d("tag1", "value: " + mobileValues[position] +" position: "+ position);

            button.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Button b = (Button) v.findViewById(R.id.button);
                    String mobile = b.getText().toString();
                    Log.d("tag1", "button: " + mobile);
                    if (mobile.equals("Bäm 1")){
                        play(R.raw.bam1);
                    } else if (mobile.equals("Buz")){
                        play(R.raw.buz);
                    } else if (mobile.equals("Bäm 2")){
                        play(R.raw.bam2);
                    } else if (mobile.equals("Wir nehmen das Geld")){
                        play(R.raw.gold2);
                    }
                }
            });

        } else {
            gridView = (View) convertView;
        }

        return gridView;
    }

    @Override
    public int getCount() {
        return mobileValues.length;
    }

    @Override
    public Object getItem(int position) {
        return null;
    }

    @Override
    public long getItemId(int position) {
        return 0;
    }
}

Currently I'm passing in a string array with 26 Items. When it comes to the 20th button to draw, the position drops to 0 and the Button displays a wrong Text. How do I fix this?


Solution

  • The problem with your code is that you are not setting the test for the views outside the screen. The correct code should be something like this

    public class ButtonAdapter extends BaseAdapter {
        private Context context;
        private final String[] mobileValues;
        private View.OnClickListener onClListener = new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Button b = (Button) v.findViewById(R.id.button);
                String mobile = b.getText().toString();
                Log.d("tag1", "button: " + mobile);
                if (mobile.equals("Bäm 1")){
                    play(R.raw.bam1);
                } else if (mobile.equals("Buz")){
                    play(R.raw.buz);
                } else if (mobile.equals("Bäm 2")){
                    play(R.raw.bam2);
                } else if (mobile.equals("Wir nehmen das Geld")){
                    play(R.raw.gold2);
                }
            }
        };
    
        public ButtonAdapter(Context context, String[] mobileValues) {
            this.context = context;
            this.mobileValues = mobileValues;
        }
    
        public View getView(int position, View convertView, ViewGroup parent) {
            LayoutInflater inflater = (LayoutInflater) context
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    
            if (convertView == null) {
                convertView = inflater.inflate(R.layout.button, parent, false);
            }
            Button button = (Button) convertView
                    .findViewById(R.id.button);
            button.setText(mobileValues[position]);
            button.setOnClickListener(onClListener);
    
            return convertView;
        }
    
        @Override
        public int getCount() {
            return mobileValues != null ? mobileValues.length : 0;
        }
    
        @Override
        public Object getItem(int position) {
            return mobileValues[position];
        }
    
        @Override
        public long getItemId(int position) {
            return position;
        }
    }