Home » Android » android – Scrolling a Gallery enables pressed state and removes click listener from subitems

android – Scrolling a Gallery enables pressed state and removes click listener from subitems

Posted by: admin June 15, 2020 Leave a comment

Questions:

I have a gallery of fairly complicated items. Each item is composed of an image and 2 buttons. When the gallery loads everything works, the buttons do what they are supposed to, and the pressed state for the buttons happens only on actual press of the buttons.

However as soon as I scroll the gallery, the buttons stop working and clicking anywhere enables the pressed state for the buttons.

I have tried embedding everything in a LinearLayout that doesn’t pass on OnDown events as per this answer however, this just blocks click events.

I am aware that Gallery is not the ideal widget for complicated layouts like this, but I am wondering if there is a better workaround for this issue.

UPDATE:

I will try to explain the architecture a bit. I have a FragmentActivity which contains a ListFragment, which is made up of just a ListView.

The ListView is made up of groups of smaller elements(Bettable) along with some meta information. These groups are implemented as Gallerys. Specifically
I have extended Gallery (called OneGallery), that does several things, it makes sure that only one item is scrolled at a time, and also
transforms the gallery items as the scrolling is happening. Here is the code for that

Here is the adapter for the Gallery

And here is the code for the Bettable layout

How to&Answers:

Try to add a new wrapper layout around the child view and override the setPressed. The gallery will stop passing its state on the children and the mentioned undesired behavior that you describe will be fixed.

Answer:

This is views recycling. Try to use ViewHolder pattern and set up item state for every getView call. If you want to do that you must hold view state in your complex object. For example your complex object contains TextView, ImageView and CheckBox

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

    ComplexObject co = objects.get(position);

    // A ViewHolder keeps references to children views to avoid unneccessary calls
    // to findViewById() on each row.
    ViewHolder holder;

    // When convertView is not null, we can reuse it directly, there is no need
    // to reinflate it. We only inflate a new View when the convertView supplied
    // by ListView is null.
    if (convertView == null) {
        convertView = mInflater.inflate(R.layout.list_item_icon_text, null);

        // Creates a ViewHolder and store references to the two children views
        // we want to bind data to.
        holder = new ViewHolder();
        holder.text = (TextView) convertView.findViewById(R.id.text);
        holder.icon = (ImageView) convertView.findViewById(R.id.icon);
        holder.checkbox = (CheckBox)convertView.findViewById(R.id.checkbox);
        convertView.setTag(holder);
    } else {
        // Get the ViewHolder back to get fast access to the TextView
        // and the ImageView.
        holder = (ViewHolder) convertView.getTag();
    }

    // Bind the data efficiently with the holder.
    holder.text.setText(co.getText());
    holder.icon.setImageBitmap((position & 1) == 1 ? mIcon1 : mIcon2);
    holder.checkbox.setChecked(co.isChecked());

    holder.checkbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
                @Override
                public void onCheckedChanged(CompoundButton compoundButton, boolean isChecked) {
                    co.setChecked(isChecked);
                }
            });


    return convertView;
}

protected class ViewHolder{
    TextView text;
    ImageView icon;
    CheckBox checkbox; 

}   

Hope it will be helpful