美文网首页Android开发Android知识半栈工程师
安卓自定义一个二级标签选择器

安卓自定义一个二级标签选择器

作者: 勤能不能补拙 | 来源:发表于2017-12-05 18:46 被阅读0次

    先来看效果图吧“


    gif5新文件.gif

    这个东西的总体思路是记录每一个标签的在viewgroup中的位置,然后再让每个一级标签对应起来他的二级标签,除啊是状态的时候显示所有的一级标签,然后点击每个一级标签的时候,让所有的一级标签收回到中心点位置,并让对应的二级标签扩展到半径外的位置,然后让上一级按钮显示出来,这么做可能在初始化的时候时间要久一点,应为要一次性划出所有的便签,但是之后的操作很流畅,不过有个问题就是如果一级以及二级标签太多的话(十几个),界面会显得很乱,并且标签可能会重叠,不过项目中一般那种巨大的便签不会这么设计,除非有病,这个用来做一些量不是很大的二级选择还是不错的,(一般一级标签,二级标签到不要超过十个效果应该最好)

    
    public class  RoundView  extends  RelativeLayout {
    
    //屏幕的宽
    
    private int  widthPixels;
    
    //屏幕的高
    
    private int  heightPixels;
    
    //默认半径
    
    private int  defultR=300;
    
    private  Contex  tcontext;
    //这个是一级标签的数据
    private  ArrayList  data=new  ArrayList();
    //这个是二级标签的数据,大集合中有个小集合,小集合对应的的位置就是一级标签的为止
    private ArrayList<ArrayList<String>> childData = new ArrayList();
    
    //这个是每个二级标签对应的位置(这个位置是指在整个view group中的子view的位置)
    private ArrayList<ArrayList<Integer>> childDataindex = new ArrayList();
    
    //这个是一级标签对应的位置
    private ArrayList<Integer> Dataindex = new ArrayList();
    
    //这个是当前打开的二级标签位置的集合
    private ArrayList<Integer> integers;
    
    private intmainMenuColor=0;
    
    private intitemMenuColor=0;
    
    public intget  WidthPixels() {
    
    return  widthPixels;
    
    }
    
    public void  setWidth  Pixels(int  widthPixels) {
    
    this.widthPixels= widthPixels;
    
    }
    
    public intget  MainMenuColor() {
    
    return  mainMenuColor;
    
    }
    
    public void  setMainMenuColor(int  mainMenuColor) {
    
    this.mainMenuColor= mainMenuColor;
    
    }
    
    public intget  ItemMenuColor() {
    
    return  itemMenuColor;
    
    }
    
    public void  setItemMenuColor(int  itemMenuColor) {
    
    this.itemMenuColor= itemMenuColor;
    
    }
    
    public  RoundView(Context context) {
    
    this(context, null);
    
    }
    
    public  RoundView(Context context,AttributeSet attrs) {
    
    this(context,attrs,0);
    
    }
    
    public  RoundView(Context context,AttributeSet attrs, int  defStyleAttr) {
    
    super(context,attrs,defStyleAttr);
    
    init(context);
    
    }
     //这个方法是将一个一级便签和其对应的二级标签添加到集合中的
     public void setData(String s, ArrayList<String> child) {
            //将一组数据添加到集合
            int childsize = 0;
            for (int i = 0; i < childDataindex.size(); i++) {
                childsize = childsize + childDataindex.get(i).size();
            }
            Dataindex.add(data.size() + childsize);
            data.add(s);
    
            childData.add(child);
            //主按钮的长度
            int size = data.size();
            int childsize1 = 0;
            for (int i = 0; i < childDataindex.size(); i++) {
                childsize1 = childsize1 + childDataindex.get(i).size();
            }
            int allSize = size + childsize1;
    
            ArrayList<Integer> integers = new ArrayList<>();
            for (int i = 0; i < child.size(); i++) {
                integers.add(allSize + i);
            }
            childDataindex.add(integers);
        }
    //这个是初始化方法
     private void init(final Context context) {
            this.context = context;
            DisplayMetrics dm = new DisplayMetrics();
            Activity activity = (Activity) context;
            activity.getWindowManager().getDefaultDisplay().getMetrics(dm);
            widthPixels = dm.widthPixels;
            heightPixels = dm.heightPixels;
            defultR = widthPixels / 5;
    
            for (int i = 0; i < data.size(); i++) {
                final TextView textView = new TextView(context);
                LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(defultR, defultR);
                textView.setLayoutParams(layoutParams);
                textView.setGravity(Gravity.CENTER);
                textView.setTextSize(18);
                textView.setEnabled(false);
                textView.setVisibility(INVISIBLE);
                textView.setText(data.get(i));
                textView.setTextColor(Color.WHITE);
                //textView.setBackgroundColor(Color.RED);
                textView.setBackgroundResource(R.drawable.tv_shap);
                if (mainMenuColor!=0){
                    GradientDrawable p = (GradientDrawable)textView.getBackground();
                    p.setColor(mainMenuColor);
                }
                final int finalI = i;
                textView.setOnClickListener(new OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        downAnimal(Dataindex.get(finalI), finalI);
                    }
                });
                this.addView(textView);
                final ArrayList<String> arrayList = childData.get(i);
                for (int k = 0; k < arrayList.size(); k++) {
                    final TextView textView1 = new TextView(context);
                    LinearLayout.LayoutParams layoutParams1 = new LinearLayout.LayoutParams(defultR, defultR);
                    textView1.setLayoutParams(layoutParams1);
                    textView1.setGravity(Gravity.CENTER);
                    textView1.setTextSize(18);
                    textView1.setText(arrayList.get(k));
                    textView1.setTextColor(Color.WHITE);
                    //textView.setBackgroundColor(Color.RED);
                    textView1.setBackgroundResource(R.drawable.tv1_shap);
                    if (itemMenuColor!=0){
                        GradientDrawable p1 = (GradientDrawable)textView1.getBackground();
                        p1.setColor(itemMenuColor);
                    }
                    final int finalK = k;
                    textView1.setOnClickListener(new OnClickListener() {
                        @Override
                        public void onClick(View view) {
                            Toast.makeText(context, arrayList.get(finalK), Toast.LENGTH_SHORT).show();
                        }
                    });
                    textView1.setVisibility(INVISIBLE);
                    this.addView(textView1);
                }
            }
        }
    
    
     @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            measureChildren(widthMeasureSpec, heightMeasureSpec);
        }
    
        //重新布局
        @Override
        protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
            int childCount = this.getChildCount();
            for (int i = 0; i < childCount; i++) {
                final TextView child = (TextView) this.getChildAt(i);
                int width = child.getLayoutParams().width;
                int height = child.getLayoutParams().height;
                child.layout(right / 2 - width / 2, bottom / 2 - height / 2, right / 2 + width / 2, bottom / 2 + height / 2);
            }
        }
    
       //调用这个方法来创建这个组合标签
       public void creat() {
            init(context);
            initRetunt();
            upAninmal();
        }
        //这个方法是设置上一级按钮的
        private void initRetunt() {
            final TextView textView2 = new TextView(context);
            LinearLayout.LayoutParams layoutParams2 = new                     
            LinearLayout.LayoutParams(defultR, defultR);
            textView2.setLayoutParams(layoutParams2);
            textView2.setGravity(Gravity.CENTER);
            textView2.setTextSize(18);
            textView2.setText("上一级");
            textView2.setTextColor(Color.WHITE);
            //textView.setBackgroundColor(Color.RED);
            textView2.setBackgroundResource(R.drawable.tv_shap);
            if (mainMenuColor!=0){
                GradientDrawable p2 = (GradientDrawable)textView2.getBackground();
                p2.setColor(mainMenuColor);
            }
            textView2.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View view) {
                    retunAnimal();
                }
            });
            textView2.setVisibility(INVISIBLE);
            this.addView(textView2);
        }
     //这个方法是二级标签展开的动画
     private void upAninmal() {
            int childCount = data.size();
            int childitem = childCount;
            //百分比
            if (childitem != 0) {
                int roud = 360 / childitem;
                for (int i = 0; i < childCount; i++) {
                    double x = 0;
                    double y = 0;
                    final TextView childAt = (TextView) getChildAt(Dataindex.get(i));
                    x = 0 + defultR*1.5 * Math.cos(roud * i * Math.PI / 180);
                    y = 0 + defultR*1.5 * Math.sin(roud * i * Math.PI / 180);
                    ObjectAnimator.ofFloat(childAt, "translationX", 0, (int) x).setDuration(500).start();
                    ObjectAnimator.ofFloat(childAt, "translationY", 0, (int) y).setDuration(500).start();
                    final ObjectAnimator alpha = ObjectAnimator.ofFloat(childAt, "alpha",  1.0f).setDuration(500);
                    alpha.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                        @Override
                        public void onAnimationUpdate(ValueAnimator valueAnimator) {
                            float value = (Float) alpha.getAnimatedValue();
                            Log.d("value", String.valueOf(value));
                            if (value > 0.5f) {
                                childAt.setVisibility(VISIBLE);
                            }
                            if (value ==1f) {
                                childAt.setEnabled(true);
                            }
                        }
                    });
                    alpha.start();
                }
            }
    
        }
     //这个是关闭的动画及操作
    private void downAnimal(Integer finalI, int index) {
    
            for (int i = 0; i < data.size(); i++) {
                final View childAt = getChildAt(Dataindex.get(i));
                childAt.setEnabled(false);
                ObjectAnimator.ofFloat(childAt, "translationX", 0).setDuration(500).start();
                ObjectAnimator.ofFloat(childAt, "translationY", 0).setDuration(500).start();
                final ObjectAnimator alpha = ObjectAnimator.ofFloat(childAt, "alpha", 0f).setDuration(500);
                alpha.start();
                alpha.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                    @Override
                    public void onAnimationUpdate(ValueAnimator valueAnimator) {
                        float value = (Float) alpha.getAnimatedValue();
                        if (value <= 0.5f) {
                            childAt.setVisibility(INVISIBLE);
                        }
                    }
                });
    
            }
            integers = childDataindex.get(index);
            int childitem = integers.size();
            final TextView retun = (TextView) getChildAt(getChildCount() - 1);
            for (int i = 0; i < integers.size(); i++) {
                final View childAt = getChildAt(integers.get(i));
                int roud = 360 / childitem;
                double x = 0;
                double y = 0;
                x = 0 + defultR*1.5 * Math.cos(roud * i * Math.PI / 180);
                y = 0 + defultR*1.5 * Math.sin(roud * i * Math.PI / 180);
                ObjectAnimator.ofFloat(childAt, "translationX", 0, (int) x).setDuration(500).start();
                ObjectAnimator.ofFloat(childAt, "translationY", 0, (int) y).setDuration(500).start();
                final ObjectAnimator alpha = ObjectAnimator.ofFloat(childAt, "alpha", 0f, 0.5f
                        , 1f).setDuration(500);
                alpha.start();
                alpha.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                    @Override
                    public void onAnimationUpdate(ValueAnimator valueAnimator) {
                        float value = (Float) alpha.getAnimatedValue();
                        if (value >= 0.5f) {
                            childAt.setVisibility(VISIBLE);
                            retun.setVisibility(VISIBLE);
                        }
                        if (value==1f){
                            childAt.setEnabled(true);
                            retun.setEnabled(true);
                        }
    
                    }
                });
            }
        }
    
     /**
         * 返回上一级的动画
         */
        private void retunAnimal() {
            final TextView retun = (TextView) getChildAt(getChildCount() - 1);
            for (int i = 0; i < integers.size(); i++) {
                final View childAt = getChildAt(integers.get(i));
                ObjectAnimator.ofFloat(childAt, "translationX", 0).setDuration(500).start();
                ObjectAnimator.ofFloat(childAt, "translationY", 0).setDuration(500).start();
                final ObjectAnimator alpha = ObjectAnimator.ofFloat(childAt, "alpha", 0f).setDuration(500);
                alpha.start();
                childAt.setEnabled(false);
                retun.setEnabled(false);
                alpha.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                    @Override
                    public void onAnimationUpdate(ValueAnimator valueAnimator) {
                        float value = (Float) alpha.getAnimatedValue();
                        if (value <= 0.5f) {
                            childAt.setVisibility(INVISIBLE);
                            retun.setVisibility(INVISIBLE);
                        }
                    }
                });
            }
            upAninmal();
        }
    
    

    另外用法也很简单

     roundView = (RoundView) findViewById(R.id.mv);
            //搞一些假数据
            ArrayList<String> firstPage = new ArrayList<>();
            firstPage.add("小学");
            firstPage.add("初中");
            firstPage.add("高中");
            firstPage.add("大学");
            firstPage.add("上班族");
            firstPage.add("留学");
            firstPage.add("学前");
            ArrayList<String> secondPage = new ArrayList<>();
    
            secondPage.add("一年级");
            secondPage.add("二年级");
            secondPage.add("三年级");
            secondPage.add("四年级");
            secondPage.add("五年级");
            secondPage.add("六年级");
    
            //设置每一组标签
            for (int i = 0; i < firstPage.size(); i++) {
                roundView.setData(firstPage.get(i),secondPage);
            }
            //一级标签的颜色
            roundView.setMainMenuColor(Color.BLUE);
            //二级标签的颜色
            roundView.setItemMenuColor(Color.BLUE);
            roundView.creat();
    

    另外就是这个是自己随便写的一个demo,项目中没有使用,所以没做神们扩展,很多可以搞的属性没有搞,可以封装的地方没有封装,请见谅,只是像请大神指点这个思路怎们样,怎么优化呢
    代码地址
    https://github.com/wxxewx/RoundMenu

    相关文章

      网友评论

        本文标题:安卓自定义一个二级标签选择器

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