列表视图:如何处理状态pressed和激活之间的延迟 [英] listview: how to handle delay between state pressed and activated

查看:127
本文介绍了列表视图:如何处理状态pressed和激活之间的延迟的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的目标结果
当用户点击一个列表视图项改变背景颜色,直到列表项不再激活的项目(以单项选择模式F.E.,用户点击另一个列表项)。

My goal
When the user taps an item in a listview the item changes background color until the list item is no longer activated (f.e. in single choice mode, the user taps another list item).

我的问题结果
在列表视图简单的项目挖掘时,有pressed状态和列表视图项的激活状态之间有一个小的延迟;这将导致ListView项为短暂闪烁(因为它恢复到设定的激活状态之前pssed状态未$ P $)。

My problem
when tapped on an item in a listview briefly, there is a small delay between the pressed state and the activated state of the listview item; this causes the listview item to flash momentarily (because it reverts to unpressed state before the activated state is set).

在水龙头持续时间短这只发生,当你点击它不再出现是pressed状态和激活状态之间没有延迟。

This only happens when the tap duration is short, when you tap it longer there is no delay between the pressed state and the activated state.

我可以产生这个问题(在三星S3 - Android 4.3的),使用这个简单的测试code:

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

main.xml中(含列表视图的定义)

<?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手动设置激活状态。没有帮助。

already tried
Setting the activated state manually in the OnItemClickListener. Doesn't help.

丑陋的黑客结果
添加以下code到我的ListItemView类似乎工作,但它也看起来像一个丑陋的黑客攻击:

ugly hack
Adding the following code to my 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);
    }
}

基本上,这延迟设置状态到非pressed,所以激活状态总是首先设置(即,当延迟足够长)。

basically, this delays setting the state to unpressed, so the activated state is always set first (that is, when the delay is long enough).

推荐答案

你finaly找到一个解决办法?
到目前为止,我还发现,以避免'忽悠'最好的解决方法是增加一个 exitFadeDuration ,例如背景选择器(它的工作原理也是在列表中选择):

Did you finaly find a solution ? The best workaround I have found so far to avoid the 'flicker' is to add an exitFadeDuration, for example in the background selector (it works also in the list selector):

<?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:整数/ config_shortAnimTime 是慢了一点对我的口味

这篇关于列表视图:如何处理状态pressed和激活之间的延迟的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆