先来看效果图吧“
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
网友评论