Listview: how to handle the delay between pressed and pressed

My goal
When a user deletes an item in a list, the item changes the background color until the list item is activated (for example, in single-selection mode, the user deletes another item in the list).

My problem is
when I briefly click on an item in the list, there is a slight delay between the clicked state and the activated state of the list item; this causes the listview element to flash instantly (because it returns to the state without clicking before setting the activated state).

This happens only with a short length of the tap, when you press it longer, there is no delay between the pressed and the active state.

I can create a problem (on Samsung S3 - Android 4.3) using this simple test code:

main.xml (containing the list definition)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="vertical"
              android:layout_width="match_parent"
              android:layout_height="match_parent">

    <ListView
            android:id="@+id/listView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:cacheColorHint="@android:color/white"
            android:background="@android:color/white"
            android:divider="@android:color/black"
            android:dividerHeight="1dp"
            android:choiceMode="singleChoice"
            />

</LinearLayout>

listitem.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/rootLayout"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:orientation="horizontal"
        android:background="@drawable/selector">
</LinearLayout>

selector.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true" android:drawable="@android:color/holo_blue_dark"/>
    <item android:state_activated="true" android:drawable="@android:color/holo_blue_dark"/>
    <item android:drawable="@android:color/white"/>
</selector>

MyActivity.java

package com.example.Test;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.*;

public class MyActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        ListView listView = (ListView) findViewById(R.id.listView);
        listView.setAdapter(new ListAdapter(this,
                new String[] {"item 1", "item 2", "item 3", "item 4"}));
    }

    private class ListAdapter extends ArrayAdapter<String> {
        public ListAdapter(Context context, String[] objects) {
            super(context, 0, objects);
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            if (convertView == null) {
                convertView = new ListItemView(getContext());
            }

            return convertView;
        }
    }

    private class ListItemView extends LinearLayout {
        public ListItemView(Context context) {
            super(context);
            LayoutInflater.from(context).inflate(R.layout.listitem, this, true);
        }
    }
}

already tried
setting the activated state manually in OnItemClickListener. Does not help.

ugly hack
Adding the following code to the ListItemView class seems to work, but it also looks like an ugly hack:

@Override
public void setPressed(boolean pressed) {
    if (pressed) {
        super.setPressed(true);
    } else {
        postDelayed(new Runnable() {
            @Override
            public void run() {
                ListItemView.super.setPressed(false);
            }
        }, 100);
    }
}

basically, it delays the state setting on click, so the activated state is always set first (that is, when the delay is long enough).

+1
source share
1 answer

? , , "", exitFadeDuration, , ( ):

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"
       android:exitFadeDuration="_some_integer_value_>">
    <item android:state_pressed="true" android:drawable="@android:color/holo_blue_dark"/>
    <item android:state_activated="true" android:drawable="@android:color/holo_blue_dark"/>
    <item android:drawable="@android:color/white"/>
</selector>

100 , @android:integer/config_shortAnimTime

0

Source: https://habr.com/ru/post/1616871/


All Articles