listview:如何处理按下和激活状态之间的延迟

时间:2014-03-15 10:38:31

标签: android listview android-listview state

我的目标
当用户点击列表视图中的项目时,该项目会更改背景颜色,直到列表项目不再被激活(例如,在单选模式下,用户点击另一个列表项目。)

我的问题
当简单地点击列表视图中的项目时,在按下状态和列表视图项目的激活状态之间存在小的延迟;这会导致listview项暂时闪烁(因为它在设置激活状态之前恢复到未压缩状态)。

这仅在点击持续时间很短时才会发生,当您点击它时,按下状态和激活状态之间没有延迟。

我可以使用这个简单的测试代码产生问题(在Samsung S3 - Android 4.3上):

main.xml(包含listview定义)

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

已经尝试
在OnItemClickListener中手动设置激活状态。没有帮助。

丑陋的黑客
将以下代码添加到我的ListItemView类似乎可行,但它看起来也像一个丑陋的黑客:

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

基本上,这会延迟将状态设置为未按下,因此始终首先设置激活状态(即,当延迟足够长时)。

1 个答案:

答案 0 :(得分:0)

你最终找到了解决方案吗? 到目前为止,我发现了最好的解决方法,以避免闪烁&#39;是添加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对我来说有点太慢了