美文网首页
笔记:MaterialDesign(二)--控/组件简单使用

笔记:MaterialDesign(二)--控/组件简单使用

作者: RoJacKing | 来源:发表于2018-05-10 18:22 被阅读52次

    MaterialDesign学习笔记,学习共勉
    MaterialDesign笔记(一)--控/组件简单使用
    MaterialDesign笔记(二)--控/组件简单使用

    一、ItemTouchHelper的简单使用

    1、MainActivity.java

    public class MainActivity extends AppCompatActivity implements ItemDragListener {
    
        private List<String> mData = new ArrayList<>();
        private RecyclerView mRv;
        private ItemTouchHelperAdapter mAdapter;//adapter
        private MyItemTouchHelperCallback mCallback;//自定义触摸回调
        private ItemTouchHelper mItemTouchHelper;//系统的
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            mRv = (RecyclerView) findViewById(R.id.rv);
    
            initData();
    //        initDecoration();//初始化修饰布局(首字母提示)
            initRecyclerView();
    
        }
    
        //初始化修饰布局(首字母提示),效果不友好所以注释了,没有加pinyin4j包就不要打开注释
        //如果要打开就加这段依赖compile 'com.github.open-android:pinyin4j:2.5.0'
    //    private void initDecoration() {
    //        MyDecorationThree decorationThree = new MyDecorationThree(this, mData);
    //        mRv.addItemDecoration(decorationThree);
    //    }
    
        //初始化数据
        private void initData() {
    
            for (int i = 0; i < Cheeses.NAMES.length; i++) {
                mData.add(Cheeses.NAMES[i]);
            }
        }
    
        //初始化recyclerview,关联adapter
        private void initRecyclerView() {
            //普通的   recyclerview与adapter关联
    
            //因为mainactivity实现了ItemDragListener接口,所以可以传this,代表ItemDragListener
            mAdapter = new ItemTouchHelperAdapter(mData,this);
            mRv.setLayoutManager(new LinearLayoutManager(this));
            mRv.setAdapter(mAdapter);
    
            //给recyclerview.adapter设置触摸回调ItemTouchHelper.Callback
            // (这个是我们自定义的MyItemTouchHelperCallback)
            mCallback = new MyItemTouchHelperCallback(mAdapter);
            mItemTouchHelper = new ItemTouchHelper(mCallback);
            mItemTouchHelper.attachToRecyclerView(mRv);//绑定触摸回调
    
        }
    
        /**
         * imageview的触摸回调
         *
         * 示例:ItemTouchHelper.startDrag()   只是示例,不要可去除这个方法
         * 功能:  按下imageview就可以实现拖拽功能
         * 说明:实现这个回调方法----执行ItemTouchHelper.startDrag()---就会
         *            执行ItemTouchHelper.Callback----就会执行我们自定义的MyItemTouchHelperCallback)
         *
         * @param viewHolder
         */
        @Override
        public void onStartDrags(RecyclerView.ViewHolder viewHolder) {
            mItemTouchHelper.startDrag(viewHolder);//系统方法ItemTouchHelper.startDrag()
        }
    }
    

    2、activity.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
                  android:layout_width="match_parent"
                  android:layout_height="match_parent"
                  android:orientation="vertical">
    
        <android.support.v7.widget.RecyclerView
            android:id="@+id/rv"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>
    
    
    </LinearLayout>
    

    3、Adapter--ItemTouchHelperAdapter.java

    /**
     * Created by ${chenyuexueer} 
     *
     * 说明:普通的 RecyclerView.Adapter  只是在里面添加了几个触摸回调的方法
     */
    
    public class ItemTouchHelperAdapter extends  RecyclerView.Adapter<ItemTouchHelperAdapter.ItemTouchHelperViewHolder> implements ItemMoveListener {
    
        private List<String> mData;//数据
    
        private ItemDragListener mItemDragListener;//imageview的触摸回调
    
        //构造方法,初始化数据等
        public ItemTouchHelperAdapter(List<String> mData, ItemDragListener mItemDragListener) {
            this.mData = mData;
            this.mItemDragListener = mItemDragListener;
        }
    
        //recyclerview adapter 的方法 得到item布局对象
        @Override
        public ItemTouchHelperViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    
            // LayoutInflater.from()像充气球一样充入一个view
            View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_touch_helper, parent, false);
            return new ItemTouchHelperViewHolder(itemView);
        }
    
        //recyclerview adapter 的方法 绑定数据
        @Override
        public void onBindViewHolder(final ItemTouchHelperViewHolder holder, int position) {
    
            holder.mTvStr.setText(mData.get(position));//TextView 绑定数据
    
            /**
             *  imagview添加触摸监听,点下这个imageview执行回调,这个回调是执行
             *  ItemTouchHelper.startDrag(viewHolder);系统的代码     从而我们自定义的
             *  ItemTouchHelper.CallBack()代码,实现可拖拽效果
             */
            holder.mIvDrag.setOnTouchListener(new View.OnTouchListener() {
                /**
                 *
                 * @param view  view添加触摸监听的view对象
                 *
                 * @param motionEvent  触摸事件
                 *
                 * MotionEvent.ACTION_DOWN 表示用户的手指刚接触到屏幕
                 * MotionEvent.ACTION_MOVE 表示用户的手指正在移动
                 * MotionEvent.ACTION_UP 表示用户的手指从屏幕上抬起
                 * Cancel   事件取消
                 *
                 * @return  返回值true/false
                 *
                 * 返回值为false的时候,只会执行down方法,不会执行move和up.
                 * 只有在true的时候,三个都会执行,可打开注释
                 * 注释这个mItemDragListener.onStartDrags(viewHolder);
                 * 看一下效果,不过可能看不太清(左右移动(上下移动被接手了)
                 * 最好自己写一个
                 *
                 */
    
                @Override
                public boolean onTouch(View view, MotionEvent motionEvent) {
    
                    /**
                     * 执行触摸回调,这个回调方法在activity那边实现了
                     * (在这里实现也行,不过要改代码,这里就不示例了)
                     */
                    mItemDragListener.onStartDrags(holder);
    //                switch (motionEvent.getAction()) {
    //                    case MotionEvent.ACTION_DOWN:
    //                        Log.e("TAG==","ACTION_DOWN");
    //                        break;
    //                    case MotionEvent.ACTION_MOVE:
    //                        Log.e("TAG==","ACTION_MOVE");
    //                        break;
    //                    case MotionEvent.ACTION_UP:
    //                        Log.e("TAG==","ACTION_UP");
    //                        break;
    //                }
    
                    return false;
                }
            });
    
        }
    
        //实现ItemMoveListener接口的回调方法
        @Override
        public boolean onItemMove(int fromPosition, int toPosition) {
            //系统提供的方法   交换数据
            Collections.swap(mData, fromPosition, toPosition);
            //RecyclerView.Adapter刷新
            notifyItemMoved(fromPosition, toPosition);
            return true;
        }
    
        //实现ItemMoveListener接口的回调方法
        @Override
        public boolean onItemRemove(int position) {
            //删除数据
            mData.remove(position);
            //RecyclerView.Adapter提供的  移除方法  并  刷新
            notifyItemRemoved(position);
            return true;
        }
    
        //recyclerview adapter 的方法 返回item条数
        @Override
        public int getItemCount() {
            return mData.size()>0?mData.size():0;
        }
    
        //普通的    RecyclerView.ViewHolder
        class ItemTouchHelperViewHolder extends RecyclerView.ViewHolder {
    
            TextView mTvStr;
            ImageView mIvDrag;
    
            public ItemTouchHelperViewHolder(View itemView) {
                super(itemView);
                mTvStr = (TextView) itemView.findViewById(R.id.tvStr);
                mIvDrag = (ImageView) itemView.findViewById(R.id.ivDrag);
            }
        }
    }
    

    4、自定义ItemTouchHelper.Callback------MyItemTouchHelperCallback.java

    
    /**
     * Created by ${chenyuexueer} 
     *
     * 说明:自定义触摸回调
     *
     * 1、继承 ItemTouchHelper.Callback实现重写getMovementFlags、onMove、onSwiped这三个方法
     * 2、初始化ItemMoveListener(由于ItemTouchHelperAdapter实现了这
     *      个接口并实例化了方法,所以可以直接赋值,具体请自行百度)-----看  关注①
     * 3、开启item长按拖拽功能
     *      到了这一步已经可以实现了我们想要的,后面是实现一些动画效果等
     * 4、拖拽时添加动画和视觉效果onSelectedChanged,clearView,onChildDraw
     *       onSelectedChanged,clearView这两个方法要一起用,否则...(你可以试着注释clearView看看)
     *
     */
    
    public class MyItemTouchHelperCallback extends ItemTouchHelper.Callback {
    
        ItemMoveListener mItemMoveListener;
    
        //2、初始化ItemMoveListener
        public MyItemTouchHelperCallback(ItemTouchHelperAdapter mAdapter) {//构造方法,初始化数据等
            mItemMoveListener = mAdapter;//初始化ItemMoveListener---------关注①
        }
    
        /**
         * 1.1、重写getMovementFlags
         *
         * 获取动作标识
         * 动作标识分:dragFlags和swipeFlags
         * dragFlags:列表滚动方向的动作标识(如竖直列表就是上和下,水平列表就是左和右)
         * wipeFlags:与列表滚动方向垂直的动作标识(如竖直列表就是左和右,水平列表就是上和下)
         */
        @Override
        public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
            int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
            int swipeFlags = ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;
            int flags = makeMovementFlags(dragFlags, swipeFlags);//系统方法,返回动作标记
            return flags;
        }
    
        /**
         *
         * 1.2、onMove
         *
         * 当item拖拽移动时触发----执行回调
         *
         * @param recyclerView
         * @param viewHolder       当前被拖拽的item的viewHolder
         * @param target 当前被拖拽的item下方的另一个item的viewHolder,
         *                           这个值会跟着你拖拽的位置变化而变化,简单的说就是
         *                           替换到了目的viewHolder位置(不知道这么说准不准确,反正就是这个意思)
         * @return
         */
        @Override
        public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
            Log.e("TAG","当前拖拽的viewholder=="+viewHolder+"拖到了这个位置的target=="+target);
            return mItemMoveListener.onItemMove(viewHolder.getAdapterPosition(), target.getAdapterPosition());
        }
    
        /**
         * 1.3、onSwiped
         *
         * 当item侧滑出去时触发(竖直列表是侧滑,水平列表是竖滑)
         *
         * @param viewHolder
         * @param direction  滑动的方向
         * 可以打开注释看一下效果,不过这里只能看到向左右的情况,
         *                   要看上下的自己写代码实现哈!!
         */
        @Override
        public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
            //1--UP     2--DOWN     4--LEFT     8--RIGHT
    //        Log.e("TAG","滑动的方向数字值=="+direction);
    //        switch (direction){
    //            case 1:
    //                Log.e("TAG","滑动的方向=="+direction+"--UP向上");
    //                break;
    //            case 2:
    //                Log.e("TAG","滑动的方向=="+direction+"--DOWN向下");
    //                break;
    //            case 4:
    //                Log.e("TAG","滑动的方向=="+direction+"--LEFT向左");
    //                break;
    //            case 8:
    //                Log.e("TAG","滑动的方向=="+direction+"--RIGHT向右");
    //                break;
    //        }
    
            mItemMoveListener.onItemRemove(viewHolder.getAdapterPosition());
        }
    
        /**
         * 是否开启item长按拖拽功能
         */
        @Override
        public boolean isLongPressDragEnabled() {
            return true;
        }
    
    //=====================下面是实现动画视觉效果等=============
        /**
         * 当item被拖拽或侧滑时触发,背景颜色变灰
         *
         * @param viewHolder
         * @param actionState 当前item的状态
         */
        @Override
        public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
            super.onSelectedChanged(viewHolder, actionState);
            //不管是拖拽或是侧滑,背景色都要变化
            if (actionState != ItemTouchHelper.ACTION_STATE_IDLE)
                viewHolder.itemView.setBackgroundColor(viewHolder.itemView.getContext().getResources().getColor(android.R.color.darker_gray));
        }
    
        /**
         * 当item的交互动画结束时触发,背景颜色变回白色
         *
         * @param recyclerView
         * @param viewHolder
         */
        @Override
        public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
            super.clearView(recyclerView, viewHolder);
            viewHolder.itemView.setBackgroundColor(viewHolder.itemView.getContext().getResources().getColor(android.R.color.white));
    
            viewHolder.itemView.setAlpha(1);
            viewHolder.itemView.setScaleY(1);
        }
    
        /**
         * 侧滑时触发,视觉效果----item像是被压扁的视觉效果
         *
         * @param c
         * @param recyclerView
         * @param viewHolder
         * @param dX
         * @param dY
         * @param actionState
         * @param isCurrentlyActive
         */
        @Override
        public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
            super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
            if (actionState == ItemTouchHelper.ACTION_STATE_SWIPE) {
                float value = 1 - Math.abs(dX) / viewHolder.itemView.getWidth();
                viewHolder.itemView.setAlpha(value);
                viewHolder.itemView.setScaleY(value);
            }
        }
    }
    

    5.1、ItemMoveListener自定义接口

    /**
     * Created by ${chenyuexueer}
     *
     * 说明:整个item条目的触摸监听回调
     */
    
    public interface ItemMoveListener {
    
        //整个item条目的触摸移动事件回调,主要是用于 交换数据 、 刷新数据
        boolean onItemMove(int fromPosition, int toPosition);
    
        //整个item条目的触摸删除事件回调,主要是用于  刷新数据
        boolean onItemRemove(int position);
    }
    

    5.2、ItemDragListener自定义接口

    /**
     * Created by ${chenyuexueer}
     *
     * 说明:imageview的触摸回调,按下imageview,实现拖拽功能
     *            接口回调,只是示例,可以不要这个功能
     */
    
    public interface ItemDragListener {
        //按下回调
        void onStartDrags(RecyclerView.ViewHolder viewHolder);
    }
    

    6、数据Cheeses.java----NAMES[]

    
    /**
     * Created by ${chenyuexueer} on 2018/5/9.
     * 说明:姓名数据
     */
    
    public class Cheeses {
    
        public static final String[] NAMES = new String[] { "宋江", "卢俊义", "吴用",
                "公孙胜", "关胜", "林冲", "秦明", "呼延灼", "花荣", "柴进", "李应", "朱仝", "鲁智深",
                "武松", "董平", "张清", "杨志", "徐宁", "索超", "戴宗", "刘唐", "李逵", "史进", "穆弘",
                "雷横", "李俊", "阮小二", "张横", "阮小五", " 张顺", "阮小七", "杨雄", "石秀", "解珍",
                " 解宝", "燕青", "朱武", "黄信", "孙立", "宣赞", "郝思文", "韩滔", "彭玘", "单廷珪",
                "魏定国", "萧让", "裴宣", "欧鹏", "邓飞", " 燕顺", "杨林", "凌振", "蒋敬", "吕方",
                "郭 盛", "安道全", "皇甫端", "王英", "扈三娘", "鲍旭", "樊瑞", "孔明", "孔亮", "项充",
                "李衮", "金大坚", "马麟", "童威", "童猛", "孟康", "侯健", "陈达", "杨春", "郑天寿",
                "陶宗旺", "宋清", "乐和", "龚旺", "丁得孙", "穆春", "曹正", "宋万", "杜迁", "薛永", "施恩",
                "周通", "李忠", "杜兴", "汤隆", "邹渊", "邹润", "朱富", "朱贵", "蔡福", "蔡庆", "李立",
                "李云", "焦挺", "石勇", "孙新", "顾大嫂", "张青", "孙二娘", " 王定六", "郁保四", "白胜",
                "时迁", "段景柱" };
    
    }
    
    示例1.gif

    额外示例 可以结合Decoration实现各种效果,其一比如下图

    (效果不太友好,算是bug吗,有待优化,这里只是示例)

    示例2.gif

    实现上图效果,代码如下:

    ①、把上面的MainActivity.java中的 注释 初始化修饰布局(首字母提示)方法打开注释,算了,我还是把代码全部贴上吧
    ②、结合RecyclerView.ItemDecoration

    1.1、MainActivity.java
    
    public class MainActivity extends AppCompatActivity implements ItemDragListener {
    
        private List<String> mData = new ArrayList<>();
        private RecyclerView mRv;
        private ItemTouchHelperAdapter mAdapter;//adapter
        private MyItemTouchHelperCallback mCallback;//自定义触摸回调
        private ItemTouchHelper mItemTouchHelper;//系统的
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            mRv = (RecyclerView) findViewById(R.id.rv);
    
            initData();
            initDecoration();//初始化修饰布局(首字母提示)
            initRecyclerView();
    
        }
    
        //初始化修饰布局(首字母提示),效果不友好所以注释了,没有加pinyin4j包就不要打开注释
        //如果要打开就加这段依赖compile 'com.github.open-android:pinyin4j:2.5.0'
        private void initDecoration() {
            MyDecorationThree decorationThree = new MyDecorationThree(this, mData);
            mRv.addItemDecoration(decorationThree);
        }
    
        //初始化数据
        private void initData() {
    
            for (int i = 0; i < Cheeses.NAMES.length; i++) {
                mData.add(Cheeses.NAMES[i]);
            }
        }
    
        //初始化recyclerview,关联adapter
        private void initRecyclerView() {
            //普通的   recyclerview与adapter关联
    
            //因为mainactivity实现了ItemDragListener接口,所以可以传this,代表ItemDragListener
            mAdapter = new ItemTouchHelperAdapter(mData,this);
            mRv.setLayoutManager(new LinearLayoutManager(this));
            mRv.setAdapter(mAdapter);
    
            //给recyclerview.adapter设置触摸回调ItemTouchHelper.Callback
            // (这个是我们自定义的MyItemTouchHelperCallback)
            mCallback = new MyItemTouchHelperCallback(mAdapter);
            mItemTouchHelper = new ItemTouchHelper(mCallback);
            mItemTouchHelper.attachToRecyclerView(mRv);//绑定触摸回调
    
        }
    
        /**
         * imageview的触摸回调
         *
         * 示例:ItemTouchHelper.startDrag()   只是示例,不要可去除这个方法
         * 功能:  按下imageview就可以实现拖拽功能
         * 说明:实现这个回调方法----执行ItemTouchHelper.startDrag()---就会
         *            执行ItemTouchHelper.Callback----就会执行我们自定义的MyItemTouchHelperCallback)
         *
         * @param viewHolder
         */
        @Override
        public void onStartDrags(RecyclerView.ViewHolder viewHolder) {
            mItemTouchHelper.startDrag(viewHolder);//系统方法ItemTouchHelper.startDrag()
        }
    }
    
    1.2、MyDecorationThree.java
    public class MyDecorationThree extends RecyclerView.ItemDecoration {
    
        Context mContext;
        List<String> mData;
        Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);//画笔
    
        public MyDecorationThree(Context context, List<String> data) {
            mContext = context;
            mData = data;
            //画笔字体大小与颜色
            paint.setTextSize(sp2px(16));
            paint.setColor(Color.RED);
        }
    
        @Override
        public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
            super.onDraw(c, parent, state);
            drawLetterToItemLeft(c, parent);
        }
    
        /**
         * 绘制方法
         * @param c     画布
         * @param parent    RecyclerView
         */
        private void drawLetterToItemLeft(Canvas c, RecyclerView parent) {
    
            RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
            if (!(layoutManager instanceof LinearLayoutManager)){
                return;
            }
    
            int childCount = parent.getChildCount();
    
            for (int i = 0; i < childCount; i++) {
                int position = ((LinearLayoutManager) layoutManager).findFirstVisibleItemPosition() + i;
                View child = parent.getChildAt(i);
                RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
                float left = 0;
                float top = child.getTop() - params.topMargin;
                float right = child.getLeft() - params.leftMargin;
                float bottom = child.getBottom() + params.bottomMargin;
                float width = right - left;
                float height = bottom - (bottom - top) / 2;
                //当前名字拼音的第一个字母
                String letter = PinyinUtils.getPinyin(mData.get(position)).charAt(0) + "";
                if (position == 0) {
                    drawLetter(letter, width, height, c, parent);
                } else {
                    String preLetter = PinyinUtils.getPinyin(mData.get(position - 1)).charAt(0) + "";
                    if (!letter.equalsIgnoreCase(preLetter)) {
                        drawLetter(letter, width, height, c, parent);
                    }
                }
            }
        }
    
        private void drawLetter(String letter, float width, float height, Canvas c, RecyclerView parent) {
            float fontLength = getFontLength(paint, letter);
            float fontHeight = getFontHeight(paint);
            float tx = (width - fontLength) / 2;
            float ty = height - fontHeight / 2 + getFontLeading(paint);
            c.drawText(letter, tx, ty, paint);
        }
    
        @Override
        public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
            super.getItemOffsets(outRect, view, parent, state);
            outRect.set(dip2px(40), 0, 0, 0);
        }
    
        private int dip2px(int dip) {
            float density = mContext.getResources().getDisplayMetrics().density;
            int px = (int) (dip * density + 0.5f);
            return px;
        }
    
        public int sp2px(int sp) {
            return (int) (TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, sp, mContext.getResources().getDisplayMetrics()) + 0.5f);
        }
    
    
        /**
         * 返回指定笔和指定字符串的长度
         */
        private float getFontLength(Paint paint, String str) {
            return paint.measureText(str);
        }
    
        /**
         * 返回指定笔的文字高度
         */
        private float getFontHeight(Paint paint) {
            Paint.FontMetrics fm = paint.getFontMetrics();
            return fm.descent - fm.ascent;
        }
    
    
        /**
         * 返回指定笔离文字顶部的基准距离
         */
        private float getFontLeading(Paint paint) {
            Paint.FontMetrics fm = paint.getFontMetrics();
            return fm.leading - fm.ascent;
        }
    }
    
    1.3、PinyinUtils.java
    /**
     * Created by ${chenyuexueer}
     * 
     * 说明:拼音工具(需要依赖或者导入pinyin4j-2.5.0.jar)
     */
    
    public class PinyinUtils {
    
        /**
         * 根据传入的字符串(包含汉字),得到拼音
         * 如:
         *
         * 好学 -> HAOXUE
         * 好 学*& -> HAOXUE
         * 好学y2 -> HAOXUE
         *
         * @param str 字符串
         * @return
         */
        public static String getPinyin(String str) {
    
            HanyuPinyinOutputFormat format = new HanyuPinyinOutputFormat();
            format.setCaseType(HanyuPinyinCaseType.UPPERCASE);
            format.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
    
            StringBuilder sb = new StringBuilder();
    
            char[] charArray = str.toCharArray();
            for (int i = 0; i < charArray.length; i++) {
                char c = charArray[i];
                // 如果是空格, 跳过
                if (Character.isWhitespace(c)) {
                    continue;
                }
                if (c >= -127 && c < 128 || !(c >= 0x4E00 && c <= 0x9FA5)) {
                    // 满足条件 ,则肯定不是汉字
                    sb.append(c);
                } else {
                    String s = "";
                    try {
                        // 通过char得到拼音集合. 单 -> dan, shan
                        s = PinyinHelper.toHanyuPinyinStringArray(c, format)[0];
                        sb.append(s);
                    } catch (BadHanyuPinyinOutputFormatCombination e) {
                        e.printStackTrace();
                        sb.append(s);
                    }
                }
            }
    
            return sb.toString();
        }
    
    }
    
    如果缺代码就从一、(1-6)找,不确定全部文件有没有贴上,没检查(懒癌晚期)

    二、TextInputLayout 简单使用

    1、MainActivity.java

    public class MainActivity extends AppCompatActivity {
    
        private TextInputLayout mTextInputLayout;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            mTextInputLayout = (TextInputLayout) findViewById(R.id.textInputLayout);
    
            //开启计数
            mTextInputLayout.setCounterEnabled(true);
            //最大长度6个
            mTextInputLayout.setCounterMaxLength(6);
    
            //定义错误提示
            mTextInputLayout.getEditText().addTextChangedListener(new MyTextWatch(mTextInputLayout, "长度不能超过6个字符"));
    
        }
        class MyTextWatch implements TextWatcher {
    
            TextInputLayout mTextInputLayout;
            String mErrorTip;
    
            public MyTextWatch(TextInputLayout textInputLayout, String errorTip) {
                mTextInputLayout = textInputLayout;
                mErrorTip = errorTip;
            }
    
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
    
            }
    
            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
    
            }
    
            @Override
            public void afterTextChanged(Editable s) {
                if (mTextInputLayout.getEditText().getText().toString().trim().length() > 6) {
                    mTextInputLayout.setErrorEnabled(true);
                    mTextInputLayout.setError(mErrorTip);
                } else {
                    mTextInputLayout.setErrorEnabled(false);
                }
            }
        }
    }
    

    2、activity_main.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
                  xmlns:app="http://schemas.android.com/apk/res-auto"
                  android:layout_width="match_parent"
                  android:layout_height="match_parent"
                  android:orientation="vertical">
    
        <android.support.design.widget.TextInputLayout
            android:id="@+id/textInputLayout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:errorEnabled="true"
            app:hintAnimationEnabled="true"
            app:hintEnabled="false">
    
            <EditText
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="请输入用户名"/>
    
        </android.support.design.widget.TextInputLayout>
    
        <android.support.design.widget.TextInputLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:hintAnimationEnabled="true"
            app:passwordToggleDrawable="@mipmap/ic_launcher"
            app:passwordToggleEnabled="true"
            app:passwordToggleTint="@color/colorPrimary">
    
            <EditText
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="请输入密码"
                android:inputType="textPassword"/>
        </android.support.design.widget.TextInputLayout>
    </LinearLayout>
    

    三、ToolBar 的简单使用

    image.png
    ToolBar 可以做很多内容,这里只记录SearchView的简单使用

    3.1、SearchView

    • 使用过程中遇到错误:
      Caused by: java.lang.IllegalStateException: This Activity already has an action bar supplied by the window decor. Do not request Window.FEATURE_SUPPORT_ACTION_BAR and set windowActionBar to false in your theme to use a Toolbar instead.
    • 描述:
      由于Activity已存在ActionBar,所以使用Toolbar进行替换时出错.你可以换主题也可以增加values/styles的 资源文件
    • 解决方案:http://blog.csdn.net/zhaokaiqiang1992/article/details/47442691

    3.1.1、MainActivity.java

    public class MainActivity extends AppCompatActivity {
    
        private Toolbar mToolbar;
        private SearchView mSearchView;
    
        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            mToolbar = (Toolbar) findViewById(R.id.toolbar);
            setSupportActionBar(mToolbar);
        }
    
        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
            getMenuInflater().inflate(R.menu.search_view, menu);
            MenuItem item = menu.findItem(R.id.menu_search);
            mSearchView = (SearchView) MenuItemCompat.getActionView(item);
    
            /*------------------ SearchView有三种默认展开搜索框的设置方式,区别如下: ------------------*/
            //设置搜索框直接展开显示。左侧有放大镜(在搜索框中) 右侧有叉叉 可以关闭搜索框
            mSearchView.setIconified(false);
            //设置搜索框直接展开显示。左侧有放大镜(在搜索框外) 右侧无叉叉 有输入内容后有叉叉 不能关闭搜索框
            mSearchView.setIconifiedByDefault(false);
            //设置搜索框直接展开显示。左侧有无放大镜(在搜索框中) 右侧无叉叉 有输入内容后有叉叉 不能关闭搜索框
            mSearchView.onActionViewExpanded();
    
            //设置最大宽度
            //        mSearchView.setMaxWidth(500);
            //设置是否显示搜索框展开时的提交按钮
            //        mSearchView.setSubmitButtonEnabled(true);
            //设置输入框提示语
                    mSearchView.setQueryHint("hint");
    
            //搜索框展开时后面叉叉按钮的点击事件
            mSearchView.setOnCloseListener(new SearchView.OnCloseListener() {
                @Override
                public boolean onClose() {
                    Toast.makeText(getApplicationContext(), "Close", Toast.LENGTH_SHORT).show();
                    return false;
                }
            });
            //搜索图标按钮(打开搜索框的按钮)的点击事件
            mSearchView.setOnSearchClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Toast.makeText(getApplicationContext(), "Open", Toast.LENGTH_SHORT).show();
                }
            });
            //搜索框文字变化监听
            mSearchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
                @Override
                public boolean onQueryTextSubmit(String s) {
                    Log.e("CSDN_LQR", "TextSubmit : " + s);
                    return false;
                }
    
                @Override
                public boolean onQueryTextChange(String s) {
                    Log.e("CSDN_LQR", "TextChange --> " + s);
                    return false;
                }
            });
    
            //        mSearchView.setSuggestionsAdapter();
            return super.onCreateOptionsMenu(menu);
        }
    
        //右上角的MenuItem的选择事件 
        @Override
        public boolean onOptionsItemSelected(MenuItem item) {
    
            Log.e("TAG==",item.getTitle().toString());
    
            return super.onOptionsItemSelected(item);
        }
    }
    

    3.1.2、activity_main.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
                  xmlns:app="http://schemas.android.com/apk/res-auto"
                  android:layout_width="match_parent"
                  android:layout_height="match_parent"
                  android:orientation="vertical">
    
        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            android:navigationIcon="@mipmap/ic_launcher"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
            app:title="title"
            app:titleTextColor="@android:color/white"/>
    
    </LinearLayout>
    

    3.1.3、search_view.xml 资源文件res/menu/search_view.xml

    <?xml version="1.0" encoding="utf-8"?>
    <menu xmlns:android="http://schemas.android.com/apk/res/android"
          xmlns:app="http://schemas.android.com/apk/res-auto"
          xmlns:tools="http://schemas.android.com/tools">
        <item
            android:id="@+id/menu_search"
            android:orderInCategory="100"
            android:title="搜索"
            app:actionViewClass="android.support.v7.widget.SearchView"
            app:showAsAction="always"
            />
        <item
            android:id="@+id/scan_local_music"
            android:icon="@mipmap/ic_launcher"
            android:orderInCategory="100"
            android:title="扫描本地音乐"
            app:showAsAction="never"
            />
        <item
            android:id="@+id/select_sort_way"
            android:icon="@mipmap/ic_launcher_round"
            android:orderInCategory="100"
            android:title="选择排序方式"
            app:showAsAction="never"
            />
        <item
            android:id="@+id/get_cover_lyrics"
            android:icon="@mipmap/ic_launcher"
            android:orderInCategory="100"
            android:title="获取封面歌词"
            app:showAsAction="never"
            />
        <item
            android:id="@+id/imporve_tone_quality"
            android:icon="@mipmap/ic_launcher_round"
            android:orderInCategory="100"
            android:title="升级音质"
            app:showAsAction="never"
            />
    </menu>
    
    SearchView.gif

    3.2、SearchView仿网易云本地音乐搜索

    3.2.1、MainActivity.java
    public class MainActivity extends AppCompatActivity {
    
        private ListView mLv;
        private SearchView mSearchView;
        private SearchView.SearchAutoComplete mSearchAutoComplete;
    
        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    
            //将setSupportActionBar(toolbar)放在setNavigationOnClickListener()之前设置才行
            setSupportActionBar(toolbar);
            //相当于返回键的监听
            toolbar.setNavigationOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (mSearchAutoComplete.isShown()) {
                        try {
                            mSearchAutoComplete.setText("");
                            //①、利用反射方式,调用收起SearchView的onCloseClicked()方法
                            Method method = mSearchView.getClass().getDeclaredMethod("onCloseClicked");
                            method.setAccessible(true);
                            method.invoke(mSearchView);
    
                            //②、或者mSearchView.setIconified(true)直接调用onCloseClicked()方法,可自行测试看效果
    
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    } else {
                        finish();
                    }
                }
            });
    
            mLv = (ListView) findViewById(R.id.lv);
        }
    
        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
    
            getMenuInflater().inflate(R.menu.search_view, menu);//给右上角的MenuItem充入布局菜单
            MenuItem searchItem = menu.findItem(R.id.menu_search);//得到一个MenuItem对象
    
            //通过MenuItem得到SearchView
            mSearchView = (SearchView) MenuItemCompat.getActionView(searchItem);
            //相当于输入框(不知这样说准不准确)
            mSearchAutoComplete = (SearchView.SearchAutoComplete) mSearchView.findViewById(R.id.search_src_text);
            mSearchView.setQueryHint("搜索本地歌曲by code");
    
            //设置输入框提示文字样式
            mSearchAutoComplete.setHintTextColor(getResources().getColor(android.R.color.darker_gray));
            mSearchAutoComplete.setTextColor(getResources().getColor(android.R.color.background_light));
            mSearchAutoComplete.setTextSize(14);
            //设置触发查询的最少字符数(默认2个字符才会触发查询)
            mSearchAutoComplete.setThreshold(1);
    
            //设置搜索框有字时显示叉叉,无字时隐藏叉叉
            mSearchView.onActionViewExpanded();
            //是否展开状态,也就是是否可以输入编辑
            mSearchView.setIconified(true);
    
            //放大镜  默认为true在框内,设置false则在框外
    //        mSearchView.setIconifiedByDefault(false);
            //是否显示提交按钮,就是有一个向右的三角形
            // 设置默认无内容时的文字提示
    //        mSearchView.setQueryHint("情输入歌曲名查找");
    
            //设置输入框提示文字样式
    //        mSearchAutoComplete.setHintTextColor(getResources().getColor(android.R.color.white));//设置提示文字颜色
    //        mSearchAutoComplete.setTextColor(getResources().getColor(android.R.color.white));//设置内容文字颜色
    
            //修改搜索框控件间的间隔(这样只是为了更加接近网易云音乐的搜索框)
            // 还有一种方式,res/style里面,请看activity_main.xml
            LinearLayout search_edit_frame = (LinearLayout) mSearchView.findViewById(R.id.search_edit_frame);
            ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) search_edit_frame.getLayoutParams();
            params.leftMargin = 0;
            params.rightMargin = 0;
            search_edit_frame.setLayoutParams(params);
    
            //监听SearchView的内容 ,提交按钮的事件监听
            mSearchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
                //提交按钮的点击事件
                @Override
                public boolean onQueryTextSubmit(String s) {
                    return false;
                }
                //当输入框内容改变的时候回调
                @Override
                public boolean onQueryTextChange(String s) {
    
                    Cursor cursor = TextUtils.isEmpty(s) ? null : queryData(s);
    
                    //                if (mSearchView.getSuggestionsAdapter() == null) {
                    //                    mSearchView.setSuggestionsAdapter(new SimpleCursorAdapter(SearchViewActivity2.this, R.layout.item_layout, cursor, new String[]{"name"}, new int[]{R.id.text1}));
                    //                } else {
                    //                    mSearchView.getSuggestionsAdapter().changeCursor(cursor);
                    //                }
                    setAdapter(cursor);
    
                    return false;
                }
            });
    
            return super.onCreateOptionsMenu(menu);
        }
    
        // 让菜单同时显示图标和文字
        @Override
        public boolean onMenuOpened(int featureId, Menu menu) {
            if (menu != null) {
                if (menu.getClass().getSimpleName().equalsIgnoreCase("MenuBuilder")) {
                    try {
                        //①、反射方式
                        Method method = menu.getClass().getDeclaredMethod("setOptionalIconsVisible", Boolean.TYPE);
                        method.setAccessible(true);
                        method.invoke(menu, true);
                        //②、。。。
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
            return super.onMenuOpened(featureId, menu);
        }
    
        //数据库查询
        private Cursor queryData(String key) {
            SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(getFilesDir() + "music.db", null);
            Cursor cursor = null;
            try {
                String querySql = "select * from tb_music where name like '%" + key + "%'";
                cursor = db.rawQuery(querySql, null);
                Log.e("CSDN_LQR", "querySql = " + querySql);
            } catch (Exception e) {
                e.printStackTrace();
                String createSql = "create table tb_music (_id integer primary key autoincrement,name varchar(100))";
                db.execSQL(createSql);
    
                String insertSql = "insert into tb_music values (null,?)";
                for (int i = 0; i < Cheeses.NAMES.length; i++) {
                    db.execSQL(insertSql, new String[]{Cheeses.NAMES[i]});
                }
    
                String querySql = "select * from tb_music where name like '%" + key + "%'";
                cursor = db.rawQuery(querySql, null);
    
                Log.e("CSDN_LQR", "createSql = " + createSql);
                Log.e("CSDN_LQR", "querySql = " + querySql);
            }
            return cursor;
        }
    
        //listview的adapter
        private void setAdapter(Cursor cursor) {
            if (mLv.getAdapter() == null) {
                SimpleCursorAdapter adapter = new SimpleCursorAdapter(MainActivity.this, R.layout.item_layout, cursor, new String[]{"name"}, new int[]{R.id.text1});
                mLv.setAdapter(adapter);
            } else {
                ((SimpleCursorAdapter) mLv.getAdapter()).changeCursor(cursor);
            }
        }
    }
    
    3.2.2、activity_main.xml
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
                  xmlns:app="http://schemas.android.com/apk/res-auto"
                  android:layout_width="match_parent"
                  android:layout_height="match_parent"
                  android:orientation="vertical">
    
        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:fillViewport="true"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:navigationIcon="@mipmap/ic_launcher"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
            app:title="本地音乐"
            app:titleTextColor="@android:color/white"/>
    
        <!--当ScrollView内容不足的时候,设置其height="match_parent"属性,结果还是wrap_content。使用android:fillViewport="true"-->
        <!--NavigationIcon和标题之间的距离-->
    
        <!--在res/style.xml,写入下面代码,可修改navigationIcon和SearchView之间的距离过大-->
        <!--<style name="ToolbarStyle" parent="Base.Widget.AppCompat.Toolbar">-->
            <!--<item name="contentInsetStart">0dp</item>-->
            <!--<item name="contentInsetStartWithNavigation">0dp</item>-->
        <!--</style>-->
        <!---->
        
        <ListView
            android:id="@+id/lv"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:divider="@android:color/black"
            android:dividerHeight="1dp"></ListView>
        
    </LinearLayout>
    
    3.2.3、search_view.xml

    同上----3.1.3、search_view.xml 资源文件res/menu/search_view.xml

    3.2.4、Adapter的item布局item_layout.xml
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
                  android:layout_width="match_parent"
                  android:layout_height="match_parent"
                  android:orientation="vertical">
        <!--android:id="@android:id/text1"-->
        <TextView
            android:id="@+id/text1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center_vertical"
            android:minHeight="?android:attr/listPreferredItemHeightSmall"
            android:paddingLeft="10dp"
            android:paddingRight="10dp"
            android:textAppearance="?android:attr/textAppearanceListItemSmall"
            android:textColor="@android:color/black"/>
    </LinearLayout>
    
    3.2.5、数据Cheeses.NAMES [ ]
    /**
     * Created by ${chenyuexueer} 
     * 说明:数据
     */
    
    public class Cheeses {
    
        public static final String[] NAMES = new String[] { "宋江", "卢俊义", "吴用",
                "公孙胜", "关胜", "林冲", "秦明", "呼延灼", "花荣", "柴进", "李应", "朱仝", "鲁智深",
                "武松", "董平", "张清", "杨志", "徐宁", "索超", "戴宗", "刘唐", "李逵", "史进", "穆弘",
                "雷横", "李俊", "阮小二", "张横", "阮小五", " 张顺", "阮小七", "杨雄", "石秀", "解珍",
                " 解宝", "燕青", "朱武", "黄信", "孙立", "宣赞", "郝思文", "韩滔", "彭玘", "单廷珪",
                "魏定国", "萧让", "裴宣", "欧鹏", "邓飞", " 燕顺", "杨林", "凌振", "蒋敬", "吕方",
                "郭 盛", "安道全", "皇甫端", "王英", "扈三娘", "鲍旭", "樊瑞", "孔明", "孔亮", "项充",
                "李衮", "金大坚", "马麟", "童威", "童猛", "孟康", "侯健", "陈达", "杨春", "郑天寿",
                "陶宗旺", "宋清", "乐和", "龚旺", "丁得孙", "穆春", "曹正", "宋万", "杜迁", "薛永", "施恩",
                "周通", "李忠", "杜兴", "汤隆", "邹渊", "邹润", "朱富", "朱贵", "蔡福", "蔡庆", "李立",
                "李云", "焦挺", "石勇", "孙新", "顾大嫂", "张青", "孙二娘", " 王定六", "郁保四", "白胜",
                "时迁", "段景柱" };
    
    }
    
    SearchView仿网易云音乐搜索.gif
    四、Palette 的简单使用

    暂时不记录在笔记中,以后有空记得就补上

    image.png
    五、CardView卡片效果

    暂时不记录在笔记中,以后有空记得就补上

    六、FloatingActionButton浮动效果

    暂时不记录在笔记中,以后有空记得就补上

    相关文章

      网友评论

          本文标题:笔记:MaterialDesign(二)--控/组件简单使用

          本文链接:https://www.haomeiwen.com/subject/idkorftx.html