增加Android下spinner控件的点击下拉列表自动更新事件并实例应用--USB摄像头在spinner内下拉更新(一)

转载请注明:http://blog.csdn.net/hubbybob1/article/details/57457364
最近在编写一个Android下自动读取USB摄像头的应用,主要是读取摄像头的VID与PID,思考以什么样的方式读取,因此做了一个小的demo,使用Android的spinner控件是最好的选择,但是spinner的一个最大的缺点就是在下拉列表的时候无法自动更新列表,网上很多使用的案例都是把spinner的列表写死了,无法自动更新,我个人认为这个很不方便,于是就开始我的做法。

首先来看一下spinner的编写流程(普通流程):
1.定义spinner:private Spinner spinner;
2.定义spinner的数据列表:private ArrayList datas ;
3.找到控件:spinner = (ClickControlledSpinner) this.findViewById(R.id.spinner);
4.建立ArrayAdapter,并绑定数据列表;
5.设置下拉显示模式;
6.spnner与Adaptor绑定
7.编写监听选择事件;(4,5,6步骤如下)

adapter = new ArrayAdapter<String>(this,android.R.layout.simple_spinner_dropdown_item, datas); //建立ArrayAdapter,并绑定数据列表
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);//设置下拉显示模式
spinner.setAdapter(adapter);//spnner与Adaptor绑定

这是spinner的一般流程,但是我不能使用传统的spinner,因为不具有下拉更新的功能,因此需要编写自己的spinner,在网上搜了很多,终于搜到了一个案例:请查看,非常感谢!编写ClickControlledSpinner.java,就是重写继承传统的spinner
本文使用的spinner的方式有两个simple_spinner_dropdown_item和 my_simple_spinner_self_item,如下

<!--my_simple_spinner_dropdown_item.xml
-->
<CheckedTextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@android:id/text1"
    style="?android:attr/spinnerDropDownItemStyle"
    android:layout_width="match_parent"
    android:layout_height="40dp"
    android:background="#00FF00"
    android:ellipsize="marquee"
    android:gravity="center"
    android:singleLine="true"
    android:textAlignment="inherit"
    android:textColor="#FF0000"
    android:textSize="24sp" />
<!--my_simple_spinner_self_item.xml
-->
<CheckedTextView xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@android:id/text1"
    style="?android:attr/spinnerDropDownItemStyle"
    android:textColor="#0000FF"
    android:gravity="center"
    android:singleLine="true"
    android:layout_width="match_parent"
    android:layout_height="40dp"
    android:ellipsize="marquee"
    android:textAlignment="inherit"
    android:background="#FFFFFF"/>

下面是我的activity_main.xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.spinnerdemo.MainActivity$PlaceholderFragment" >

    <com.example.spinnertest.ClickControlledSpinner
        android:id="@+id/spinner"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center_vertical" />

   <Spinner  
        android:id="@+id/spinnerTwo"  
        android:layout_width="match_parent"  
        android:layout_height="wrap_content"  
        android:layout_marginTop="50dp"  
        android:gravity="center_vertical" />  

    <!-- <ClickControlledSpinner
        android:id="@+id/spinner"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center_vertical" /> -->

    <!-- Spinner自身背景色需设置:android:background="@drawable/spinner_selector" -->

</LinearLayout>

这个地方要注意的是要使用的是自己的spinner,

<com.example.spinnertest.ClickControlledSpinner //正确
<ClickControlledSpinner //错误

虽然上面第二种写法不会出现语法错误但是会显示在Android内找不到ClickControlledSpinner这个view,而无法使用自己写的spinner。
下面就是ClickControlledSpinner.java的相关代码,通过下边自写的控件导入到代码中就可以很好应用的,要知道本案例的应用或者这个控件的使用方法请查看我的下一篇博客:增加Android下spinner控件的下拉列表自动更新事件并实例应用–USB摄像头在spinner内下拉更新(二)

import android.content.Context;  
import android.content.DialogInterface;
import android.graphics.Point;  
import android.util.AttributeSet;  
import android.util.Log;
import android.view.MotionEvent;  
import android.widget.Spinner;  

/** 
 * 继承自Spinner的自定义下拉列表框。该下拉列表有如下特点: 
 * <ol> 
 * <li>使用{@link #setOnClickMyListener(OnClickMyListener)}可监控点击事件,并可自行实现点击后的响应动作(原来Spinner的响应动作是打开列表选择框)。</li> 
 * <li>点击事件发生后,默认不再打开列表选择框,如需打开,请调用{@link #performClick()}</li> 
 * </ol> 
 * 该控件的目地在于弥补Spinner对于点击事件不能自定义响应的不足,Spinner对应点击的响应有自己的内在方案, 
 * 对外屏蔽了{@link #setOnClickListener(OnClickListener)}接口,  
 * 如果我们需要在点击控件后列表选择框出现前做某些事情(如:更新列表), 
 * 那么我们发现用Spinner根本无从下手,此控件弥补了这些不足。在监控到点击事件后,我们可执行一些动作, 
 * 动作执行完毕,只需要手动使用{@link #performClick()}显示列表选择框即可。 
 * <p /> 
 *  
 * The class inherited from Spinner. The drop-down list has the following characteristics: 
 * <ol> 
 * <li> Use {@link #setOnClickMyListener(OnClickMyListener)} to listen the click event and can implement self-fulfilling click response action (Spinner's default response action is to open the list selection box). </ li> 
 * <li> Click event occurs, the default response is no longer open the list selection box, please call {@link #performClick()} instead. </ li> 
 * </ol> 
 * The purpose of the control is to compensate for that Spinner click event can not be caught, the Spinner has its own solution with the click event response,  
 * and {@link #setOnClickListener(OnClickListener)} interface is shielded,  
 * if we need to do something (such as update list) after click event happened and before the list selection box appears, 
 * we'll find no way, but ClickControlledSpinner did, it listens the click event, can let us perform some actions after this, 
 * after actions finished, we must revoke {@link #performClick()} to display the list selection box. 
 *  
 * @date 2012/08/24 
 * @author Wison Xu 
 */  
public class ClickControlledSpinner extends Spinner {  

    public ClickControlledSpinner(Context context) {  
        super(context);  
    }  

    public ClickControlledSpinner(Context context, AttributeSet attrs, int defStyle) {  
        super(context, attrs, defStyle);  
    }  

    public ClickControlledSpinner(Context context, AttributeSet attrs) {  
        super(context, attrs);  
    }  

    private boolean isMoved = false;  
    private Point touchedPoint = new Point();  

    @Override  
    public boolean onTouchEvent(MotionEvent event) {  
        super.onTouchEvent(event);
        int x = (int) event.getRawX();  
        int y = (int) event.getRawY();  
        switch (event.getAction()) {  
        case MotionEvent.ACTION_DOWN:  
            touchedPoint.x = x;  
            touchedPoint.y = y;  
            break;  
        case MotionEvent.ACTION_MOVE:  
            isMoved = true;  
            break;  
        case MotionEvent.ACTION_UP:  
            if (isMoved) {  
                // 从上向下滑动  
                if (y - touchedPoint.y > 20) {  
                }   
                // 从下向上滑动  
                else if (touchedPoint.y - y > 20) {  
                }  
                // 滑动幅度小时,当作点击事件  
                else {  
                    onClickm();  
                }  
                isMoved = false;  
            } else {  
                onClickm();  
            }  
            break;  
        default:  
            break;  
        }  
        return true; 
    }           
    private void onClickm() {  
        Log.i("dddd", "--zz    onc  m");
        if (onClickMyListener != null && isEnabled()) {  
            // use a thread to do something which maybe spend many times.  
            new Thread() {  
                public void run() {  
                    onClickMyListener.onClickm();  
                }  
            }.start();  
        }  
    }           
    private OnClickMyListener onClickMyListener; 

    /** 
     * 注册自定义的点击事件监听 
     * Register the click event self-fulfilling listener. 
     * @param onClickMyListener 
     */  
    public void setOnClickMyListener(OnClickMyListener onClickMyListener) {  
        this.onClickMyListener = onClickMyListener;  
    }  

    /** 
     * 自定义点击事件监听. 
     * Click event self-fulfilling listener. 
     * @author Wison Xu 
     */  
    public interface OnClickMyListener {  
        /** 
         * 点击时触发 
         * 警告:该方法在非UI线程中执行 
         *  
         * Triggers when click event occurs. 
         * Warning: this method does not run in UI thread. 
         */  
        public void onClickm() ;  
    }
}  
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值