安卓状态选择器中遇到的若干问题

最近公司让做一个语音识别的功能,基本效果如下图:
这里写图片描述
看上去很简单的一张图,但是发现里边的坑实在不少.

  1. 首先,我们先分析下这个按钮:

    • 最外边是一个灰色的线性布局1
    • 里边是一个带有状态选择器的线性布局2
    • 线性布局2里边是一个带有状态选择器的imageview和textview
  2. 下边我们先给这个线性布局设置selector

    selector

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/shape_voice_unpressed" android:state_enabled="false"></item>
    <item android:drawable="@drawable/shape_voice_pressed" android:state_enabled="true"></item>
</selector>
布局
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="45dp"
        android:layout_margin="20dp"
        android:background="@drawable/selector_voice_circleboard2"
        android:gravity="center"
        android:orientation="horizontal">

    </LinearLayout>

这个时候发现:给LinearLayout设置的selector,点击后没有反应感觉很奇怪,到网上查了查,给的解决方案是添加这么一句话:

android:clickable="true"

添加上之后果然问题解决了,可是为什么会这样呢?

 Log.d("TAG", "rl_root是否可点击?==" + rl_root.isClickable());

打印的结果:

04-10 16:55:46.860 11124-11124/com.gelitenight.waveview.sample D/TAG: rl_root是否可点击?==false

也就是说默认情况下:
LinearLayout是不可点击的,不可点击的按钮自然没有android:state_pressed这个状态,添加了android:clickable=”true”或者点击事件就可以响应状态选择器中的android:state_pressed状态

3.下边我们再看我们这里不单单要让外边的LinearLayout有状态选择器,还要让里边的imageview和
textview都有状态选择器:

<LinearLayout
    android:id="@+id/ll_btn_voice"
    android:layout_width="match_parent"
    android:layout_height="45dp"
    android:background="@drawable/selector_voice_circleboard2"
    android:clickable="true"
    android:gravity="center"
    android:orientation="horizontal">
    <ImageView
        android:id="@+id/iv_btn_voice"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/selector_voice_btn2"/>
    <TextView
        android:id="@+id/tv_btn_voice"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="  按住 说出你要的商品"
        android:textColor="@color/selector_voice_textcolor2"
        android:textSize="16sp"/>
</LinearLayout>

这里只需要给外边的LinearLayout设置一个android:clickable=”true”就可以使LinearLayout和里边的
Imageview和textview的selector都生效,但是到网上找的相关的说法是,给每个子控件添加:
这里写图片描述

 android:duplicateParentState="true"

这个属性的作用:

如果设置此属性,将直接从父容器中获取绘图状态(光标,按下等)。 注意仅仅是获取绘图状态,而没有获取事件,也就是你点一下LinearLayout时Button有被点击的效果,但是不执行点击事件

然而,我发现:

只要给外边的LinearLayout设置一个android:clickable=”true”就可以达到效果,里边的Imageview和textview添加或者不添加 android:duplicateParentState=”true”,并没有什么影响.

4.最终要求的这个按钮不仅要点击后颜色状态的变化,还需要向上滑动取消录音
也就是说:需要给这个LinearLayout设置OnTouchListener

private int downY;

ll_voice_btn_content2.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        downY = (int) event.getRawY();
                        break;
                    case MotionEvent.ACTION_UP:
                        int upY = (int) event.getRawY();
                        if (Math.abs(upY - downY) > 20) {
                            Toast.makeText(TestSelectorActivity.this, "停止录音", Toast.LENGTH_SHORT).show();
                        }
                        break;
                    default:
                        break;
                }
                return true;
            }
        });

设置上去发现:刚才的状态选择器失效了,原因是因为设置了OnTouchListener后,OnTouchListener会将事件抢过来,那么要想同时实现滑动取消和状态选择器只能在代码中,动态的去设置按下的状态:setPressed(true),
不过,个人习惯性性试验setEnabled(true),下边是部分代码:

布局文件:

    <LinearLayout
        android:id="@+id/ll_voice_btn_content2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:background="#ededed"
        android:orientation="horizontal"
        android:paddingBottom="10dp"
        android:paddingLeft="25dp"
        android:paddingRight="25dp"
        android:paddingTop="10dp">

        <LinearLayout
            android:id="@+id/ll_btn_voice2"
            android:layout_width="match_parent"
            android:layout_height="45dp"
            android:background="@drawable/selector_voice_circleboard"
            android:enabled="false"
            android:gravity="center"
            android:orientation="horizontal"
            >

            <ImageView
                android:id="@+id/iv_btn_voice2"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:enabled="false"
                android:src="@drawable/selector_voice_btn"/>

            <TextView
                android:id="@+id/tv_btn_voice2"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:enabled="false"
                android:text="  按住 说出你要的商品"
                android:textColor="@color/selector_voice_textcolor"
                android:textSize="16sp"
                />
        </LinearLayout>
    </LinearLayout>

MainActivity:

public class MainActivity extends Activity {
    @ViewInject(R.id.ll_voice_btn_content2)
    private LinearLayout ll_voice_btn_content2;
    @ViewInject(R.id.ll_btn_voice2)
    private LinearLayout ll_btn_voice2;
    @ViewInject(R.id.iv_btn_voice2)
    private ImageView iv_btn_voice2;

    @ViewInject(R.id.tv_btn_voice2)
    private TextView tv_btn_voice2;

    @ViewInject(R.id.rl_root)
    private RelativeLayout rl_root;


    private int downY;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_test_selector);
        ViewUtils.inject(this);

        Log.d("TAG", "rl_root是否可点击?==" + rl_root.isClickable());

        ll_btn_voice2.setEnabled(false);
        iv_btn_voice2.setEnabled(false);
        tv_btn_voice2.setEnabled(false);

        ll_voice_btn_content2.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        downY = (int) event.getRawY();
                        ll_btn_voice2.setEnabled(true);
                        iv_btn_voice2.setEnabled(true);
                        tv_btn_voice2.setEnabled(true);

                        break;
                    case MotionEvent.ACTION_UP:
                        ll_btn_voice2.setEnabled(false);
                        iv_btn_voice2.setEnabled(false);
                        tv_btn_voice2.setEnabled(false);
                        int upY = (int) event.getRawY();
                        if (Math.abs(upY - downY) > 20) {
                            Toast.makeText(TestSelectorActivity.this, "停止录音", Toast.LENGTH_SHORT).show();
                        }
                        break;
                    default:
                        break;
                }
                return true;
            }
        });


    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值