【问题标题】:ListView item LongClick state for selector选择器的 ListView 项 LongClick 状态
【发布时间】:2023-03-25 09:28:01
【问题描述】:

在默认的 ListViews 上,如果您长按某个项目,则在注册 LongClick 期间,背景会从深蓝色变为浅蓝色(在 Galaxy Tab 上。在某些其他设备上,它是橙色到浅橙色)。我假设这是通过选择器以某种方式完成的,但到目前为止,我只看到了如何将选择器用于 state:selected、state:focused 和 state:pressed。

This page 似乎没有显示任何关于 LongClick 状态的信息,所以也许我认为这是通过选择器完成的假设不正确?

谁能告诉我默认 ListView 如何获得这种效果以及如何将其应用于其他视图?

【问题讨论】:

标签: android listview background selector


【解决方案1】:

所以结果比我想象的要困难一些,但我现在几乎可以正常工作了。

这是我最终使用的 OnTouchListener:

listOnTouchListener = new OnTouchListener() {
         public boolean onTouch(View v, MotionEvent me){
             if (me.getAction() == MotionEvent.ACTION_DOWN){
                 //This means a finger has come down on top of our view
                 //We are going to start the animation now.
                 Log.i(myTag, "Action Down");
                 Context mContext = getApplicationContext();
                 Resources res = mContext.getResources();
                 TransitionDrawable transition = (TransitionDrawable) res.getDrawable(R.drawable.listtransition);
                 v.setBackgroundDrawable(transition);
                 //LongClick took approx. 510-530 milliseconds to register after OnTouch. So I set the duration at 500 millis.
                 transition.startTransition(500);
             }else if (me.getAction() == MotionEvent.ACTION_UP){
                 //This means we didn't hold long enough to get a LongClick
                 //Set the background back to the normal one.
                 v.setBackgroundResource(R.drawable.bubblelight);

             }else if (me.getAction() == MotionEvent.ACTION_MOVE){
                 //Do Nothing
             }else if (me.getAction() == MotionEvent.ACTION_CANCEL){
                 Log.i(myTag, "Action Cancel");
                 //This means we are scrolling on the list, not trying to longpress
                 //So set the background back to the normal one.
                 v.setBackgroundResource(R.drawable.bubblelight);
             }
             return false;

         }
     };

我还在其中使用了一个 OnLongClickListener 我将背景设置回正常的。

这是过渡 XML:

<transition xmlns:android="http://schemas.android.com/apk/res/android">
  <item android:drawable="@drawable/bubblelight1" />
  <item android:drawable="@drawable/bubbledark" />
</transition>

您可能会问,bubblelight1 是怎么回事?稍后会详细介绍。

这是我在适配器中使用的 getView() 方法,用于返回列表中显示的视图:

@Override
    public View getView(int position, View convertView, ViewGroup parent) {
        v = convertView;
        if (v == null) {
            LayoutInflater vi = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            v = vi.inflate(R.layout.row, null);
        }
        Status s = items.get(position);
        if (s != null) {
            v.setOnTouchListener(listOnTouchListener);
            v.setOnLongClickListener(listOnLongClickListener);
            tweetTxt = (TextView) v.findViewById(R.id.tweetTxt);
            timeTxt = (TextView) v.findViewById(R.id.timeTxt);
            if (tweetTxt != null) {
                tweetTxt.setText(s.getText());
                tweetTxt.setOnTouchListener(gestureListener);
            }
            if(timeTxt != null){
                timeTxt.setText(getTimeFromNow(s.getCreatedAt().getTime()));
                //timeTxt.setText(s.getCreatedAt().toLocaleString());
            }
        }
        LinkifyWithTwitter.addLinks(tweetTxt, Linkify.ALL);
        return v;
    }

v.setOnTouchListener(listOnTouchListener);和 v.setOnLongClickListener(listOnLongClickListener);是我在上面显示的使用侦听器设置视图的行。

现在关于泡泡灯1。 bubblelight 和 bubbledark 是我第一次尝试时使用的九个补丁图像,每当过渡开始而不是背景从bubblelight 过渡到bubbledark 时,bubblelight 会变大并且bubbledark 会出现在bubblelight 内部。所以我有一个亮的大气泡,一个深色的小气泡,然后是里面的文字。为了解决这个问题,我制作了一个bubblelight 的副本,并完全填充了ninepatch 的底部和右侧边缘。不过,我只需要在过渡中制作第一张图像,而不是第二张。如果我以这种方式制作第二张图片,那么我的文字会从气泡中跳出,一些文本会显示在气泡的顶部和两侧。我不完全确定为什么会发生这种情况,或者为什么这个修复会起作用。但它现在可以完成这项工作。

【讨论】:

  • 您应该使用ViewConfiguration.getLongPressTimeout(),而不是固定的 500 毫秒
【解决方案2】:

http://developer.android.com/guide/topics/ui/menus.html#context-menu

当用户长按 ListView 中的某个项目并且该列表已注册以提供上下文菜单时,该列表项会通过为其背景颜色设置动画来向用户发出上下文菜单可用的信号——它从在打开上下文菜单之前将橙色变为白色。 (联系人应用程序演示了此功能。)

所以它是一个使用的动画。我相信它使用 View 自己的默认 On...() 方法来显示它。您可能需要担心为其赋予 clickable="true" 或 longClickable="true" 属性。

【讨论】:

  • 所以我将设置一个 OnTouchListener 来启动动画以转换视图的背景。有谁知道触摸注册为 LongClick 需要多长时间(以毫秒为单位)?这样我就可以同步动画的持续时间而无需反复试验
  • 经过第二次考虑,我想我可以在 OnTouch 中检查系统时间,然后在 OnLongClick 中再次检查并减去以获取持续时间。如果有人碰巧知道系统默认用于列表视图项目的动画名称,那对我仍然很有帮助。
【解决方案3】:

除了 OnTouchListener 之外,您还可以使用 Runnable 将背景恢复为其原始状态,这样您就无需在 OnLongClick 处理程序中显式执行此操作。

Handler myHandler = new Handler();
...
transition.startTransition(ViewConfiguration.getLongPressTimeout());
ResetBG r = new ResetBG(transition);
myHandler.postDelayed(r, ViewConfiguration.getLongPressTimeout());

ResetBG 在哪里:

class ResetBG implements Runnable {
    protected TransitionDrawable myTran;

    public Runnable(TransitionDrawable tran) {
        myTran = tran;
    }

    public void run() {
        myTran.resetTransition();
    }
}

【讨论】:

    猜你喜欢
    • 2013-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-23
    • 2017-10-28
    • 2019-07-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多