精华内容
下载资源
问答
  • Android 自定义下拉列表

    千次阅读 2015-09-18 15:30:12
    Android 自定义下拉列表。效果图如下。 首先,创建一个标题及箭头布局,点击后弹出下拉菜单。,代码如下所示: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/...

    Android 下拉列表也是一个比较常用的控件,但是Android自带的下拉框样式效果较差,没办法,只好自己来自定义一个。其实主要是利用弹窗来实现的,看一下效果图先~~


    我这边仅仅是实现简单的自定义控件,简单易懂,布局上有需要其他效果如边框、虚线等可自行加上。下拉列表是List,所以item也是可以根据需要进行内容上的丰富,修改适配器便可以。

    好了,进入正题。首先,我们先创建一个标题及箭头布局,目的是用于点击后弹出下拉菜单。,代码如下所示:

    接下来,创建下拉列表ListView布局,代码如下:
    <?xml version="1.0" encoding="utf-8"?>
    
    创建ListView,自然也要对应创建其Item的布局,代码如下:
    <?xml version="1.0" encoding="utf-8"?>
    
    接下来,我们来封装一个自定义控件MySpinerView,由于我没有去找向上箭头的图片资源,大家箭头自行替换。代码如下:
    package com.newland.myspinerdemo;
    
    import android.content.Context;
    import android.graphics.Color;
    import android.util.AttributeSet;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.WindowManager;
    import android.widget.ImageView;
    import android.widget.LinearLayout;
    import android.widget.RelativeLayout;
    import android.widget.TextView;
    
    import java.util.List;
    
    /**
     * 封装好的下拉列表,包括头部
     */
    public class MySpinerView extends LinearLayout implements View.OnClickListener, MySpinerAdapter.IOnItemSelectListener {
        private String mExampleString = "";
        private int mExampleColor = Color.RED;
        private float mExampleDimension = 0;
    
        private Context context;
        private RelativeLayout spiner;
        private TextView tvSpiner;
        private ImageView ivSpiner;
        private List nameList;
    
        private MySpinerPopWindow mSpinerPopWindow;
    
        public MySpinerView(Context context, AttributeSet attrs) {
            super(context, attrs);
            this.context = context;
            LayoutInflater.from(context).inflate(R.layout.sample_my_spiner_view, this);
            init(attrs, 0);
            spiner = (RelativeLayout) this.findViewById(R.id.spiner);
            spiner.setOnClickListener(this);
            tvSpiner = (TextView) this.findViewById(R.id.tv_spiner);
            ivSpiner = (ImageView) this.findViewById(R.id.iv_spiner);
        }
    
        /**
         * 设置弹出下拉表单的数据,在Activity那边得到控件后记得调用否则抛异常
         * @param nameList
         */
        public void setData(List nameList) {
            this.nameList = nameList;
            mSpinerPopWindow = new MySpinerPopWindow(context);
            mSpinerPopWindow.refreshData(nameList, 0);
            mSpinerPopWindow.setItemListener(this); // 设置下拉列表item点击的监听,响应onItemClick回调函数
        }
    
        /**
         * 头部点击事件
         * @param v
         */
        @Override
        public void onClick(View v) {
            switch (v.getId()){
                case R.id.spiner:
                    showSpinWindow();
                    break;
            }
        }
    
        /**
         * 弹出下拉列表
         */
        public void showSpinWindow() {
            /**这里还有一步要做,就是让右边箭头向上。自己替换掉ivSpiner图片**/
            mSpinerPopWindow.setWidth(((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getWidth());
            mSpinerPopWindow.showAsDropDown(tvSpiner);
        }
    
        /**
         * 下拉列表项点击事件,把选中的值显示在界面上
         * @param pos
         */
        @Override
        public void onItemClick(int pos) {
            /**这里还有一步要做,就是让右边箭头还原向下。自己替换掉ivSpiner图片**/
            if (pos >= 0 && pos <= nameList.size()) { // pos为-1就是弹窗消失,不管他
                String value = nameList.get(pos);
                tvSpiner.setText(value);
            }
        }
    
        /**
         * 初始化顶部显示数据
         * @param txt
         */
        public void initText(String txt){
            tvSpiner.setText(txt);
        }
    }
    
    自定义控件创建完毕,点击后弹出的下拉列表。

    下拉列表实际上是一个PopWindow,里面有一个ListView,所以我们新建一个自定义弹窗PopWindow。代码如下:
    package com.newland.myspinerdemo;
    
    import java.util.List;
    
    import android.content.Context;
    import android.graphics.drawable.ColorDrawable;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup.LayoutParams;
    import android.widget.AdapterView;
    import android.widget.AdapterView.OnItemClickListener;
    import android.widget.ListView;
    import android.widget.PopupWindow;
    
    /**
     * 下拉列表弹窗
     */
    public class MySpinerPopWindow extends PopupWindow implements OnItemClickListener {
    
        private Context mContext;
        private ListView mListView;
        private MySpinerAdapter mAdapter;
        private MySpinerAdapter.IOnItemSelectListener mItemSelectListener;
    
    
        public MySpinerPopWindow(Context context) {
            super(context);
            mContext = context;
            init();
        }
    
        /**
         * 为MySpinnerView提供一个item点击事件的监听器,MySpinnerView实例调用此方法设置监听
         * @param listener
         */
        public void setItemListener(MySpinerAdapter.IOnItemSelectListener listener) {
            mItemSelectListener = listener;
        }
    
        /**
         * 初始化弹窗布局
         */
        private void init() {
            View view = LayoutInflater.from(mContext).inflate(R.layout.spiner_window_layout, null);
            setContentView(view);
            setWidth(LayoutParams.WRAP_CONTENT);
            setHeight(LayoutParams.WRAP_CONTENT);
    
            setFocusable(true);
            ColorDrawable dw = new ColorDrawable(0x00);
            setBackgroundDrawable(dw);
    
            mListView = (ListView) view.findViewById(R.id.listview);
    
            mAdapter = new MySpinerAdapter(mContext);
            mListView.setAdapter(mAdapter);
            mListView.setOnItemClickListener(this);
            this.setOnDismissListener(new OnDismissListener() { // 弹窗消失的监听
                @Override
                public void onDismiss() {
                    if (mItemSelectListener != null) {
                        mItemSelectListener.onItemClick(-1); // 弹窗消失,要让布局那边的箭头还原向下,所以那边还得判断一下,>=0的数据在显示,-1就忽略掉,箭头还原
                    }
                }
            });
        }
    
        /**
         * 刷新下拉列表的数据
         * @param list
         * @param selIndex
         */
        public void refreshData(List list, int selIndex) {
            if (list != null && selIndex != -1) {
                mAdapter.refreshData(list, selIndex);
            }
        }
    
        /**
         * 下拉列表ListView的点击事件。
         * @param arg0
         * @param view
         * @param pos
         * @param arg3
         */
        @Override
        public void onItemClick(AdapterView<?> arg0, View view, int pos, long arg3) {
            dismiss();
            if (mItemSelectListener != null) {
                mItemSelectListener.onItemClick(pos); //点击后调用此方法,则MySpinerView会监听到(因为mItemSelectListener是MySpinerView那边设置的监听器)
            }
        }
    }
    
    既然是ListView,那么马上想到的就是适配器,那么我们接下来设置弹窗里面的ListView适配器,代码如下:
    package com.newland.myspinerdemo;
    
    import java.util.ArrayList;
    import java.util.List;
    
    import android.content.Context;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.BaseAdapter;
    import android.widget.TextView;
    
    public class MySpinerAdapter extends BaseAdapter {
    
        private Context mContext;
        private List mObjects = new ArrayList();
    
        private LayoutInflater mInflater;
    
        public MySpinerAdapter(Context context) {
            mContext = context;
            mInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        }
    
        /**
         * 刷新数据
         * @param objects
         * @param selIndex
         */
        public void refreshData(List objects, int selIndex) {
            mObjects = objects;
            if (selIndex < 0) {
                selIndex = 0;
            }
            if (selIndex >= mObjects.size()) {
                selIndex = mObjects.size() - 1;
            }
        }
    
    
        @Override
        public int getCount() {
            return mObjects.size();
        }
    
        @Override
        public Object getItem(int pos) {
            return mObjects.get(pos).toString();
        }
    
        @Override
        public long getItemId(int pos) {
            return pos;
        }
    
        @Override
        public View getView(int pos, View convertView, ViewGroup arg2) {
            ViewHolder viewHolder;
            if (convertView == null) {
                convertView = mInflater.inflate(R.layout.spiner_item_layout, null);
                viewHolder = new ViewHolder();
                viewHolder.mTextView = (TextView) convertView.findViewById(R.id.textView);
                convertView.setTag(viewHolder);
            } else {
                viewHolder = (ViewHolder) convertView.getTag();
            }
            String item = (String) getItem(pos);
            viewHolder.mTextView.setText(item);
            return convertView;
        }
    
        public static class ViewHolder {
            public TextView mTextView;
        }
    
        /**
         * 提供一个设置点击事件监听的接口回调
         */
        public interface IOnItemSelectListener {
            void onItemClick(int pos);
        }
    
    }
    
    好了,功能性的东西都完成了,来看看主页面布局

    主页面布局由4个自定义控件(MySpinerView)组成,代码如下:
    <?xml version="1.0" encoding="utf-8"?>
    
    最后一步,编写Activity,代码如下
    package com.newland.myspinerdemo;
    
    import java.util.ArrayList;
    import java.util.List;
    
    import android.app.Activity;
    import android.os.Bundle;
    
    public class MainActivity extends Activity{
    
        /**
         * 四个下拉列表头部数据
         */
        private String name1 = "课程类型";
        private String name2 = "教练";
        private String name3 = "卡路里";
        private String name4 = "时间";
        /**
         * 四个下拉列表数据
         */
        private List nameList1 = new ArrayList();
        private List nameList2 = new ArrayList();
        private List nameList3 = new ArrayList();
        private List nameList4 = new ArrayList();
    
        /**
         * 四个自定义下拉列表
         */
        private MySpinerView mySpinerView1;
        private MySpinerView mySpinerView2;
        private MySpinerView mySpinerView3;
        private MySpinerView mySpinerView4;
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
            setupViews();
        }
    
        /**
         * 初始化四个下拉列表
         */
        private void setupViews() {
    
            mySpinerView1 = (MySpinerView)findViewById(R.id.mysv1);
            mySpinerView1.initText(name1);
            String[] names1 = { "高级课程", "中级课程", "所有课程" };
            for (int i = 0; i < names1.length; i++) {
                nameList1.add(names1[i]);
            }
            mySpinerView1.setData(nameList1);
    
    
            mySpinerView2 = (MySpinerView)findViewById(R.id.mysv2);
            mySpinerView2.initText(name2);
            String[] names2 = {"小鱼","布拉特", "杰克逊", "菲尔顿", "希伯特"};
            for (int i = 0; i < names2.length; i++) {
                nameList2.add(names2[i]);
            }
            mySpinerView2.setData(nameList2);
    
            mySpinerView3 = (MySpinerView)findViewById(R.id.mysv3);
            mySpinerView3.initText(name3);
            String[] names3 = {"10.0","20.0", "30.0", "40.0", "50.0"};
            for (int i = 0; i < names3.length; i++) {
                nameList3.add(names3[i]);
            }
            mySpinerView3.setData(nameList3);
    
            mySpinerView4 = (MySpinerView)findViewById(R.id.mysv4);
            mySpinerView4.initText(name4);
            String[] names4 = {"1min","1hour", "1day", "1year", "forever"};
            for (int i = 0; i < names4.length; i++) {
                nameList4.add(names4[i]);
            }
            mySpinerView4.setData(nameList4);
        }
    }
    

    大功告成~~~


    附上源码下载链接:Android 自定义下拉列表 源码

    展开全文
  • Android自定义下拉列表

    2016-12-21 17:07:35
    具体可参考文章http://blog.csdn.net/mo_feng_/article/details/53786815
  • Android 自定义下拉列表 源码。简易的封装,代码易懂
  • Android自定义下拉列表,注释详细,重用性好,代码易懂
  • Android自定义下拉列表框控件源码

    热门讨论 2015-04-14 15:18:03
    基于android 4.4 开发的 自定义android 下拉列表框控件 源码,有需要的欢迎下载哈
  • Android自定义下拉列表PopupWindow

    千次阅读 2016-05-12 10:13:17
    自定义PopupWindow定义一个主类:package com.example.administrator.testpopuwindow;import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.view.View; import android....

    这里写图片描述

    这里写图片描述

    自定义PopupWindow


    定义一个主类:

    package com.example.administrator.testpopuwindow;
    
    import android.os.Bundle;
    import android.support.v7.app.AppCompatActivity;
    import android.view.View;
    import android.widget.TextView;
    
    public class MainActivity extends AppCompatActivity {
    
        private PopWinShare popwindows;
        private TextView onclink_txt;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
    
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            ways();
        }
    
        public void ways(){
            onclink_txt = (TextView) findViewById(R.id.onclink_txt);
            onclink_txt.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                        popwindows = new PopWinShare(MainActivity.this);
                        popwindows.showPopupWindow(onclink_txt);
                }
            });
    
        }
    }
    

    主类布局xml代码如下:

    <?xml version="1.0" encoding="utf-8"?>
    <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:clickable="true"
        android:orientation="vertical"
        tools:context="com.example.administrator.testpopuwindow.MainActivity"
        >
    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            android:gravity="right"
            android:background="#333333">
            <TextView
                android:id="@+id/onclink_txt"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginTop="10dp"
                android:layout_marginBottom="10dp"
                android:layout_marginRight="10dp"
                android:text="下拉菜单"
                android:textColor="#ffffff"
                android:textSize="18dp"/>
        </LinearLayout>
    
    </LinearLayout>
    

    自定义PopupWindow类,代码如下:

    package com.example.administrator.testpopuwindow;
    
    import android.app.Activity;
    import android.content.Context;
    import android.graphics.drawable.ColorDrawable;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.widget.LinearLayout;
    import android.widget.PopupWindow;
    import android.widget.Toast;
    
    /**
     * Created by Administrator on 2016-05-11.
     */
    
    public class PopWinShare extends PopupWindow {
    
        private View conentView;
        private Context context;
        public PopWinShare(final Activity context) {
    
            LayoutInflater inflater = (LayoutInflater) context
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            conentView = inflater.inflate(R.layout.popwin_share, null);
            int h = context.getWindowManager().getDefaultDisplay().getHeight();
            int w = context.getWindowManager().getDefaultDisplay().getWidth();
            // 设置SelectPicPopupWindow的View
            this.setContentView(conentView);
            // 设置SelectPicPopupWindow弹出窗体的宽
            this.setWidth(w / 2 - 100);
            // 设置SelectPicPopupWindow弹出窗体的高
            this.setHeight(LinearLayout.LayoutParams.WRAP_CONTENT);
            // 设置SelectPicPopupWindow弹出窗体可点击
            this.setFocusable(true);
            this.setOutsideTouchable(true);
            // 刷新状态
            this.update();
            // 实例化一个ColorDrawable颜色为半透明
            ColorDrawable dw = new ColorDrawable(0000000000);
            // 点back键和其他地方使其消失,设置了这个才能触发OnDismisslistener ,设置其他控件变化等操作
            this.setBackgroundDrawable(dw);
            // mPopupWindow.setAnimationStyle(android.R.style.Animation_Dialog);
            // 设置SelectPicPopupWindow弹出窗体动画效果
            this.setAnimationStyle(R.style.AnimTools);
            LinearLayout addTaskLayout = (LinearLayout) conentView
                    .findViewById(R.id.add_task_layout);
            LinearLayout teamMemberLayout = (LinearLayout) conentView
                    .findViewById(R.id.team_member_layout);
            addTaskLayout.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View arg0) {
    //                PopWinShare.this.dismiss();
                    Toast.makeText(context,"添加任务",Toast.LENGTH_LONG).show();
                }
            });
    
            teamMemberLayout.setOnClickListener(new View.OnClickListener() {
    
                @Override
                public void onClick(View v) {
    //                PopWinShare.this.dismiss();
                    Toast.makeText(context,"团队管理",Toast.LENGTH_LONG).show();
                }
            });
        }
    
        /**
         * 显示popupWindow
         *
         * @param parent
         */
        public void showPopupWindow(View parent) {
    
            if (!this.isShowing()) {
                // 以下拉方式显示popupwindow
                this.showAsDropDown(parent, parent.getLayoutParams().width / 2, 18);
    
            } else {
                this.dismiss();
            }
        }
    
    }
    

    窗口布局xml,代码如下:

    <?xml version="1.0" encoding="utf-8"?>
        <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:gravity="right"
            android:orientation="vertical" >
    
            <LinearLayout
                android:id="@+id/pop_layout2"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginRight="5dp"
                android:layout_alignParentTop="true"
                android:background="@mipmap/icon_msgbg2x"
                android:gravity="center_horizontal"
                android:orientation="vertical" >
    
                <LinearLayout
                    android:id="@+id/add_task_layout"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:orientation="horizontal"
                    android:layout_marginTop="15dp"
                    android:padding="8dp" >
    
                    <ImageView
                        android:layout_width="35dp"
                        android:layout_height="35dp"
                        android:scaleType="fitCenter"
                        android:src="@mipmap/ic_launcher" />
    
                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="fill_parent"
                        android:layout_marginLeft="10dp"
                        android:gravity="center"
                        android:text="添加任务"
                        android:textColor="#ffffff"
                        android:textSize="15dip" />
                </LinearLayout>
    
                <TextView
                    android:layout_width="fill_parent"
                    android:layout_height="0.2dp"
                    android:background="#000000" />
    
                <LinearLayout
                    android:id="@+id/team_member_layout"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:orientation="horizontal"
                    android:padding="8dp" >
    
                    <ImageView
                        android:layout_width="35dp"
                        android:layout_height="35dp"
                        android:scaleType="fitCenter"
                        android:src="@mipmap/ic_launcher" />
    
                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="fill_parent"
                        android:layout_marginLeft="10dp"
                        android:gravity="center"
                        android:text="团队成员"
                        android:textColor="#ffffff"
                        android:textSize="15dip" />
                </LinearLayout>
    
                <TextView
                    android:layout_width="fill_parent"
                    android:layout_height="0.2dp"
                    android:background="#000000" />
    
                <LinearLayout
    
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:orientation="horizontal"
                    android:padding="8dp" >
    
                    <ImageView
                        android:layout_width="35dp"
                        android:layout_height="35dp"
                        android:scaleType="fitCenter"
                        android:src="@mipmap/ic_launcher" />
    
                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="fill_parent"
                        android:layout_marginLeft="10dp"
                        android:gravity="center"
                        android:text="任务管理"
                        android:textColor="#ffffff"
                        android:textSize="15dip" />
                </LinearLayout>
            </LinearLayout>
    
        </RelativeLayout>

    弹窗动画效果xml,anim/push_in.xml:

    <?xml version="1.0" encoding="utf-8"?>
    <!-- 左上角扩大-->
    <scale   xmlns:android="http://schemas.android.com/apk/res/android"
        android:interpolator="@android:anim/accelerate_decelerate_interpolator"
        android:fromXScale="0.001"
        android:toXScale="1.0"
        android:fromYScale="0.001"
        android:toYScale="1.0"
        android:pivotX="90%"
        android:pivotY="0"
        android:duration="100" />

    弹窗动画效果xml,anim/push_out.xml:

    <?xml version="1.0" encoding="utf-8"?>
    <!-- 左上角缩小 -->
    <scale   xmlns:android="http://schemas.android.com/apk/res/android"
        android:interpolator="@android:anim/accelerate_decelerate_interpolator"
        android:fromXScale="1.0"
        android:toXScale="0.001"
        android:fromYScale="1.0"
        android:toYScale="0.001"
        android:pivotX="90%"
        android:pivotY="0"
        android:duration="200" />

    style文件:

     <style name="AnimTools" parent="@android:style/Animation">
            <item name="android:windowEnterAnimation">@anim/push_in</item>
            <item name="android:windowExitAnimation">@anim/push_out</item>
        </style>

    ok,自定义下拉PopupWindow就完成了。


    这里写图片描述

    这里写图片描述

    展开全文
  • 自定义下拉列表,跟spinner的效果一样,但不会像spinner一样弹出一个dialog,而是一popupwindow的形式弹出
  • CListView添加CListViewHeaderView作为表头,使用表头显示状态,在加入表头以后列表的数量是Adapter的数量加上1。 CListView捕捉手势操作,监听滚动事件并设置刷新事件。 public class CListView ex...

    1. 自定义ListView

    自定义CListView继承ListView,实现AbsListView.OnScrollListener接口。
    CListView添加CListViewHeaderView作为表头,使用表头显示状态,在加入表头以后列表的数量是Adapter的数量加上1。
    CListView捕捉手势操作,监听滚动事件并设置刷新事件。

    public class CListView extends ListView implements AbsListView.OnScrollListener {
        private CListViewHeaderView mHeaderView;
        private int mFirstItemIndex;
    
        private float mStartY, mCurrentY;
        private boolean mRefreshEnable, mRecord;
    
        public CListView(Context context) {
            this(context, null);
        }
    
        public CListView(Context context, AttributeSet attrs) {
            super(context, attrs);
    
            mHeaderView = new CListViewHeaderView(context);
            mHeaderView.setListView(this);
            addHeaderView(mHeaderView);
            mHeaderView.refreshFinish();
    
            setOnScrollListener(this);
        }
    
        @Override
        public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
            mFirstItemIndex = firstVisibleItem;
        }
    
        @Override
        public void onScrollStateChanged(AbsListView view, int scrollState) {
        }
    
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    // 保证触摸的y值只记录一次
                    if (!mRecord) {
                        mStartY = event.getY();
                        mRecord = true;
                    }
                    break;
                case MotionEvent.ACTION_MOVE:
                    if (!mRecord) {
                        mStartY = event.getY();
                        mRecord = true;
                    }
                    mCurrentY = event.getY();
                    if (mRefreshEnable && mFirstItemIndex == 0) {
                        mHeaderView.move((int) (mCurrentY - mStartY));
                    }
                    break;
                case MotionEvent.ACTION_UP:
                case MotionEvent.ACTION_CANCEL:
                    mCurrentY = event.getY();
                    if (mRefreshEnable && mFirstItemIndex == 0 && mRecord) {
                        mHeaderView.release((int) (mCurrentY - mStartY));
                    }
                    mRecord = false;
                    break;
            }
            return super.onTouchEvent(event);
        }
    
        /*
         * 刷新回调
         */
        public void refreshFinish() {
            mHeaderView.refreshFinish();
        }
    
        public void setOnRefreshListener(IOnRefreshListener refreshListener) {
            mRefreshEnable = (refreshListener != null);
            mHeaderView.setOnRefreshListener(refreshListener);
        }
    
        public interface IOnRefreshListener {
            void onRefreshStart();
        }
    
    }
    

    2. 列表头CListViewHeaderView

    CListViewHeaderView拥有四种状态

    • DONE,初始状态
    • PULL_TO_REFRESH,下拉刷新
    • RELEASE_TO_REFRESH,松开刷新
    • REFRESHING,刷新中

    CListViewHeaderView默认是初始状态,当进行下拉操作时,显示为下拉刷新。下拉超过3倍表头高度,显示松开刷新。正在刷新时不能进行界面操作。

    public class CListViewHeaderView extends LinearLayout {
        private final static int DONE               = 0;
        private final static int PULL_TO_REFRESH    = 1; // 下拉刷新
        private final static int RELEASE_TO_REFRESH = 2; // 放手刷新
        private final static int REFRESHING         = 3; // 刷新
    
        private final static int RATIO              = 3;
    
        private ImageView mIvArrow;
        private ProgressBar mProgressBarRefresh;
        private TextView mTvRefreshTips;
    
        private Animation mAnimCycle, mAnimReverse;
    
        private String mPullToRefresh, mReleaseToRefresh, mRefreshing;
        private int mContentHeight;
    
        private int mHeadState = DONE;
        private boolean mReverse; // 图标是否旋转
    
        private CListView mListView;
        private CListView.IOnRefreshListener mListener;
    
        public CListViewHeaderView(Context context) {
            this(context, null);
        }
    
        public CListViewHeaderView(Context context, @Nullable AttributeSet attrs) {
            super(context, attrs);
    
            inflate(context, R.layout.list_view_header_view, this);
    
            mIvArrow = findViewById(R.id.iv_arrow);
            mProgressBarRefresh = findViewById(R.id.progress_bar_refresh);
            mTvRefreshTips = findViewById(R.id.tv_refresh_tips);
    
            mAnimCycle = AnimationUtils.loadAnimation(context, R.anim.anim_list_view_rotate);
            mAnimReverse = AnimationUtils.loadAnimation(context, R.anim.anim_list_view_reverse);
    
            mContentHeight = context.getResources().getDimensionPixelOffset(R.dimen.head_view_height);
    
            mPullToRefresh = context.getString(R.string.list_view_pull_to_refresh);
            mReleaseToRefresh = context.getString(R.string.list_view_release_to_refresh);
            mRefreshing = context.getString(R.string.list_view_refreshing);
        }
    
        void setListView(CListView listView) {
            this.mListView = listView;
        }
    
        void move(int distance) {
            if (mHeadState != REFRESHING) {
                if (mHeadState == DONE) {
                    if (distance > 0) {
                        mHeadState = PULL_TO_REFRESH;
                        changeHeaderViewByState();
                    }
                }
                if (mHeadState == PULL_TO_REFRESH) {
                    if (distance >= RATIO * mContentHeight) {
                        mHeadState = RELEASE_TO_REFRESH;
                        mReverse = true;
                        changeHeaderViewByState();
                    } else if (distance <= 0) {
                        mHeadState = DONE;
                        changeHeaderViewByState();
                    }
                }
                if (mHeadState == RELEASE_TO_REFRESH) {
                    if (distance <= 0) {
                        mHeadState = DONE;
                        changeHeaderViewByState();
                    } else if (distance < RATIO * mContentHeight) {
                        mHeadState = PULL_TO_REFRESH;
                        changeHeaderViewByState();
                    }
                }
                if (mHeadState == PULL_TO_REFRESH || mHeadState == RELEASE_TO_REFRESH) {
                    if (mListView != null) {
                        mListView.setSelection(0);
                    }
                    setPadding(0, distance / RATIO - mContentHeight, 0, 0);
                }
            }
        }
    
        void release(float distance) {
            if (distance >= RATIO * mContentHeight) {
                mHeadState = REFRESHING;
            } else {
                mHeadState = DONE;
            }
            changeHeaderViewByState();
    
            if (mHeadState == REFRESHING) {
                mListener.onRefreshStart();
            }
        }
    
        void setOnRefreshListener(CListView.IOnRefreshListener listener) {
            this.mListener = listener;
        }
    
        public void refreshFinish() {
            mHeadState = DONE;
            changeHeaderViewByState();
        }
    
        private void changeHeaderViewByState() {
            switch (mHeadState) {
                case DONE:
                    setPadding(0, -1 * mContentHeight, 0, 0);
    
                    mIvArrow.clearAnimation();
                    mProgressBarRefresh.setVisibility(View.GONE);
                    mTvRefreshTips.setText(mPullToRefresh);
                    break;
                case PULL_TO_REFRESH:
                    mIvArrow.setVisibility(View.VISIBLE);
                    mIvArrow.clearAnimation();
    
                    mProgressBarRefresh.setVisibility(View.GONE);
                    mTvRefreshTips.setText(mPullToRefresh);
    
                    // 是由RELEASE_To_REFRESH状态转变来的
                    if (mReverse) {
                        mReverse = false;
                        mIvArrow.startAnimation(mAnimReverse);
                    }
                    break;
                case RELEASE_TO_REFRESH:
                    mIvArrow.setVisibility(View.VISIBLE);
                    mIvArrow.clearAnimation();
    
                    mIvArrow.startAnimation(mAnimCycle);
    
                    mProgressBarRefresh.setVisibility(View.GONE);
                    mTvRefreshTips.setText(mReleaseToRefresh);
                    break;
                case REFRESHING:
                    setPadding(0, 0, 0, 0);
    
                    mIvArrow.clearAnimation();
                    mIvArrow.setVisibility(View.GONE);
    
                    mProgressBarRefresh.setVisibility(View.VISIBLE);
                    mTvRefreshTips.setText(mRefreshing);
                    break;
            }
        }
    
    }
    

    资源文件list_view_header_view.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">
    
        <LinearLayout
            android:id="@+id/header_view"
            android:layout_width="match_parent"
            android:layout_height="@dimen/head_view_height"
            android:orientation="horizontal"
            android:gravity="center">
            <ImageView
                android:id="@+id/iv_arrow"
                android:layout_width="12dp"
                android:layout_height="12dp"
                android:src="@drawable/list_arrow"
                android:scaleType="fitCenter"
                android:visibility="gone"/>
    
            <ProgressBar
                android:id="@+id/progress_bar_refresh"
                style="?android:attr/progressBarStyleSmall"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:visibility="gone" />
    
            <TextView
                android:id="@+id/tv_refresh_tips"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="5dp"
                android:textSize="12sp"
                android:textColor="#FF000000"/>
        </LinearLayout>
    </LinearLayout>
    

    3. 界面调用

    Activity中添加CListView.IOnRefreshListener监听器,并在3秒后结束。

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    
        ...  ...
    
        final CListView listView = findViewById(R.id.list_view);
        listView.setAdapter(new ArrayAdapter<>(this,
                R.layout.list_view_item, R.id.tv_name, getResources().getStringArray(R.array.month)));
    
        listView.setOnRefreshListener(new CListView.IOnRefreshListener() {
            @Override
            public void onRefreshStart() {
                listView.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        listView.refreshFinish();
                    }
                }, 3000);
            }
        });
    }
    

    4. 效果如下

    在这里插入图片描述

    源码下载: https://github.com/nai-chen/AndroidBlog

    展开全文
  • 自定义下拉列表框: 下拉框提示信息,,prompt,,必须是dialog才可使用,添加下面style,,必须用字符串资源 style="@android:style/Widget.Spinner" android:prompt="@string/tishi" android:spinnerMode=...

    自定义下拉列表框:


    下拉框提示信息,,prompt,,必须是dialog才可使用,添加下面style,,必须用字符串资源
    style="@android:style/Widget.Spinner"
    android:prompt="@string/tishi"

    android:spinnerMode=“dialog或者dropdown”对话框/下拉框
    

    1,在activity_main.xml文件中定义一个spinner。。

    <FrameLayout 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:paddingLeft="@dimen/activity_horizontal_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
        android:paddingTop="@dimen/activity_vertical_margin"
        android:paddingBottom="@dimen/activity_vertical_margin"
        android:background="@color/white"
        tools:context=".MainActivity">
    
        <Spinner
            android:layout_marginTop="30dp"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:spinnerMode="dropdown"
            android:id="@+id/spinner"
            android:padding="10dp"
            android:background="@drawable/selector_test"
       />
      
    </FrameLayout>
    
    

    2,在和activity_main.xml同级目录下,定义一个布局文件用来显示spinner的样式。

    <?xml version="1.0" encoding="utf-8"?>
    
        <TextView xmlns:android="http://schemas.android.com/apk/res/android"
            android:id="@+id/text1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:textSize="18sp"
            android:paddingLeft="10dp"
            android:textColor="@color/blue"
    
            />
    
    

    3,在和activity_main.xml同级目录下,定义一个布局文件用来显示spinner下拉列表框的样式。

    <?xml version="1.0" encoding="utf-8"?>
    <TextView xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/text2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:textSize="18sp"
        android:paddingLeft="10dp"
        android:textColor="@color/red"
        android:background="@drawable/selector_spinner" //用了一个选择器,当被点击时样式和不被点击时样式不同
        android:layout_marginTop="5dp"
        android:padding="10dp"
    />
    
    

    4,在java文件中定义

    package com.example.syx.spinner;
    
    import android.annotation.TargetApi;
    import android.os.Build;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.view.Menu;
    import android.view.MenuItem;
    import android.view.View;
    import android.widget.AdapterView;
    import android.widget.ArrayAdapter;
    import android.widget.ImageView;
    import android.widget.Spinner;
    import android.widget.Toast;
    
    public class MainActivity extends AppCompatActivity{
    
        private Spinner spinner;
        private ArrayAdapter<String> adapter;
    
        @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            spinner =(Spinner)findViewById(R.id.spinner);
    
    //定义字符串用来显示下拉框的信息
            String[] arr=new String[]{"山东","江苏","浙江","河北"};
            //适配器,第一个参数是当前类,,,第二个参数是定义过的spinner的布局样式(也就是第二步骤里的),,第三个参数是字符串数组
            adapter = new ArrayAdapter(this,R.layout.spinner_item,arr);
    //setDropDownViewResource(),设置下拉框的样式,,,也就是第三步骤里创建的样式。      
    
      adapter.setDropDownViewResource(R.layout.spinner_item_one);
      //设置下拉框的垂直偏移量
            spinner.setDropDownVerticalOffset(100);
            //spinner.setDropDownWidth(800);
    
            spinner.setAdapter(adapter);
    
    
    
    //给spinner设置一个选择的事件监听,
            spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
                @Override
                public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                //获取数据并转化为字符串
                    String name = adapter.getItem((int) id).toString();
                    //Toast提示选择的什么
                    Toast.makeText(MainActivity.this, "你选择的是" + name, Toast.LENGTH_SHORT).show();
    
                }
    
                @Override
                public void onNothingSelected(AdapterView<?> parent) {
    
                }
            });
    
        }
    
    
    }
    
    
    展开全文
  • Android自定义下拉列表框控件

    万次阅读 2017-10-20 13:49:40
    Android中的有个原生的下拉列表控件Spinner,但是这个控件有时候不符合我们自己的要求, 比如有时候我们需要类似windows 或者web网页中常见的那种下拉列表控件,类似下图这样的: 这个时候只有自己动手...
  • 主要介绍了Android自定义Spinner下拉列表(使用ArrayAdapter和自定义Adapter实现)的相关资料,需要的朋友可以参考下

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 527
精华内容 210
关键字:

android自定义下拉列表