Android 원형 회전 메뉴 개발 실례
실현 방향:
그림 에서 알 수 있 듯 이 이 세 가지(또는 더 많 으 면 자신 이 다시 실현 해 야 한다)메뉴 는 중심 점 을 중심 으로 회전 하고 회전 은 2 층 으로 나 뉘 며 배경 회전 과 메뉴 회전,배경 회전 은 직접 회전 애니메이션 으로 이 루어 질 수 있다.메뉴 의 회전 은 중심 점 을 원심 으로 하 는 링 에 있 기 때문에 회전 각도 에 따라 이 점 이 직각 좌표계 에 있 는 좌표 점 을 구 하 는 함수(x=r*cos(rotation*3.14/180)와 y=r*sin(rotation*3.14/180)을 사용 한 다음 에 얻 은 점 의 위치 에 따라 메뉴 의 위 치 를 설정 하면 이러한 효 과 를 실현 할 수 있다.수학 이 중요 하 다 는 걸 알 수 있 습 니 다.하하~
생각 이 있 으 면 우 리 는 코드 로 실현 할 수 있다.
1.우선 사용자 정의 View 계승 상대 레이아웃 및 구조 함수 재 작성
/**
* Created by ywl on 2016/8/7.
*/
public class CircleMenuLayout extends RelativeLayout {
public CircleMenuLayout(Context context) {
this(context, null);
}
public CircleMenuLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
/**
*
* @param context
* @param attrs
* @param defStyleAttr
*/
public CircleMenuLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
this.context = context;
layoutInflater = LayoutInflater.from(context);
menuitems = new ArrayList<View>();
centerview = new View(context);//
centerview.setId(ID_CENTER_VIEW);
LayoutParams lp = new LayoutParams(0, 0);
lp.addRule(RelativeLayout.CENTER_IN_PARENT, RelativeLayout.TRUE);
addView(centerview, lp); //
progressBar = new ProgressBar(context);//
LayoutParams lp2 = new LayoutParams(dip2px(context, 90), dip2px(context, 90));
lp2.addRule(RelativeLayout.CENTER_IN_PARENT, RelativeLayout.TRUE);
addView(progressBar, lp2);
progressBar.setIndeterminateDrawable(context.getResources().getDrawable(R.mipmap.icon_circle_menu));
}
}
구조 함수 에 중심 포 지 셔 닝 점 과 회전 배경 그림 을 추가 하고 적당 한 크기 를 설정 합 니 다.2.들 어 오 는 그림 배열 과 메뉴 이름 배열 에 따라 메뉴 의 원래 위치 효 과 를 생 성 합 니 다.
/**
* 3
* @param size
* @param center_distance
*/
public void initMenuItem(int size, int center_distance, String[] titles, int[] imgs)
{
radus = 360f / size;
int width = dip2px(context, 50); //
int height = dip2px(context, 50);//
for(int i = 0; i < size; i++) //
{
int top = 0;
int left = 0;
top = -(int)(Math.sin(radus * i * 3.1415f / 180) * center_distance); //r * cos(ao * 3.14 /180 )
left = -(int)(Math.cos(radus * i * 3.1415f / 180) * center_distance); //
LayoutParams lp = new LayoutParams(dip2px(context, 50), dip2px(context, 50));
View view = layoutInflater.inflate(R.layout.item_circle_menu, this, false);
view.setTag(i);
TextView tvname = (TextView) view.findViewById(R.id.tv_name);
ImageView ivimg = (ImageView) view.findViewById(R.id.img);
tvname.setText(titles[i]);
ivimg.setImageResource(imgs[i]);
view.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {//
if(!isrun) {
tag = (int) v.getTag();
currentPosition = tag;
if(tag == 0)
{
finishdus = -360;
}
else if(tag == 1)
{
finishdus = -120;
}
else if(tag == 2)
{
finishdus = -240;
}
LayoutParams lp = (LayoutParams) v.getLayoutParams();
int l = lp.leftMargin;
int t = lp.topMargin;
if (t > -dip2px(context, 5) && l > -dip2px(context, 5)) {
oldradus = 120f;
isright = false;
} else if (t > -dip2px(context, 5) && l < -dip2px(context, 5)) {
oldradus = 120f;
isright = true;
} else if (t < -dip2px(context, 5)) {
oldradus = 0f;
}
sub = 0;
circleMenu(8, dip2px(context, 45), oldradus, isright);
}
}
});
lp.addRule(RelativeLayout.BELOW, centerview.getId());
lp.addRule(RelativeLayout.RIGHT_OF, centerview.getId());
lp.setMargins(-width / 2 + top, -height / 2 + left, 0, 0);
addView(view, lp);
menuitems.add(view);
}
handler.postDelayed(runnable, 0);
}
메뉴 의 수량 순환 에 따라 각 메뉴 의 위 치 를 계산 한 다음 해당 위치 에 해당 하 는 메뉴 를 추가 하면 메뉴 의 초기 화 를 실현 할 수 있 습 니 다.메뉴 마다 클릭 이 벤트 를 추 가 했 지만 3 개의 메뉴 만 적 용 된 경우,다른 수량의 메뉴 는 스스로 고치 거나 일반적인 방법 으로 클릭 위 치 를 계산 할 수 있 습 니 다.3.배경 회전 애니메이션:
/**
*
* @param offserradius
* @param center_distance
* @param d
* @param right
*/
public void circleMenu(float offserradius, int center_distance, float d, boolean right)
{
if(oldradus != 0)
{
progressBar.clearAnimation();
if(isright)
{
mRotateUpAnim = new RotateAnimation(bgdus, bgdus + 120,
Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
0.5f);
bgdus += 120;
}
else
{
mRotateUpAnim = new RotateAnimation(bgdus, bgdus - 120,
Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
0.5f);
bgdus -= 120;
}
lir = new LinearInterpolator();
mRotateUpAnim.setDuration(350);
mRotateUpAnim.setFillAfter(true);
mRotateUpAnim.setInterpolator(lir);
// mRotateUpAnim.setRepeatCount(Animation.INFINITE);
progressBar.startAnimation(mRotateUpAnim);
}
circleMenuItem(offserradius, center_distance, d, right);
}
이것 은 회전 각도 에 따라 회전 애니메이션 을 사용 하 는 것 이 간단 합 니 다.4.회전 메뉴:
/**
*
* @param offserradius
* @param center_distance
* @param d
* @param right
*/
public void circleMenuItem(float offserradius, int center_distance, float d, boolean right)
{
sub += offserradius;
if(sub > d)
{
if(onMenuItemSelectedListener != null)
{
onMenuItemSelectedListener.onMenuItemOnclick(tag);
}
isrun = false;
return;
}
if(right) {
offsetradus -= offserradius;
}
else
{
offsetradus += offserradius;
}
int size = menuitems.size();
int width = dip2px(context, 50);
int height = dip2px(context, 50);
for(int i = 0; i < size; i++)
{
if(Math.abs(sub - d) <= 8)
{
offsetradus = finishdus;
}
LayoutParams lp = (LayoutParams) menuitems.get(i).getLayoutParams();
float ds = radus * i + offsetradus;
int top = -(int)(Math.sin(ds * 3.1415f / 180) * center_distance); //r * cos(ao * 3.14 /180 )
int left = -(int)(Math.cos(ds * 3.1415f / 180) * center_distance);
lp.setMargins(-width / 2 + top, -height / 2 + left, 0, 0);
menuitems.get(i).requestLayout();
}
if(sub <= d) {
isrun = true;
offsetradus = offsetradus % 360;
handler.postDelayed(runnable, 5);
}
else
{
if(onMenuItemSelectedListener != null)
{
onMenuItemSelectedListener.onMenuItemOnclick(tag);
}
isrun = false;
}
}
여기 서 회전 은 초기 화 할 때 모든 메뉴 가 있 는 위치 에 따라 회전 각 도 를 구 한 다음 에 handler 를 시작 하여 점차적으로 증가 하거나 감소 하 는 각도 로 응답 하 는 위 치 를 구하 면 애니메이션 효 과 를 실현 합 니 다.5.메뉴 항목 을 수 동 으로 설정 합 니 다(제한 이 있 고 유 니 버 설 이 없습니다).
/**
*
* @param tag
*/
public void setCurrentTag(int tag)
{
if(currentPosition == tag)
{
return;
}
if(tag == 0)
{
finishdus = -360;
}
else if(tag == 1)
{
finishdus = -120;
}
else if(tag == 2)
{
finishdus = -240;
}
if(currentPosition == 0) // 0
{
if(tag == 1)
{
oldradus = 120f;
isright = true;
}
else if(tag == 2)
{
oldradus = 120f;
isright = false;
}
}
else if(currentPosition == 1)
{
if(tag == 2)
{
oldradus = 120f;
isright = true;
}
else if(tag == 0)
{
oldradus = 120f;
isright = false;
}
}
else if(currentPosition == 2)
{
if(tag == 0)
{
oldradus = 120f;
isright = true;
}
else if(tag == 1)
{
oldradus = 120f;
isright = false;
}
}
currentPosition = tag;
this.tag = tag;
sub = 0;
circleMenu(8, dip2px(context, 45), oldradus, isright);
}
이렇게 하면 회전 효 과 를 실현 할 수 있다.6.호출 방법:
(1)레이아웃 파일:
<com.ywl5320.circlemenu.CircleMenuLayout
android:id="@+id/cml_menu"
android:layout_width="150dp"
android:layout_height="150dp"
android:layout_centerHorizontal="true"
android:layout_alignParentBottom="true"
android:layout_marginBottom="92dp"/>
(2)메뉴 레이아웃 파일:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="100dp"
android:layout_height="100dp"
android:padding="5dp"
android:gravity="center">
<ImageView
android:id="@+id/img"
android:layout_width="25dp"
android:layout_height="25dp"
android:scaleType="fitXY"/>
<TextView
android:id="@+id/tv_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=" "
android:textSize="9sp"
android:gravity="center"
android:textColor="#ffffff"/>
</LinearLayout>
(3)Activity 에서 호출
<span style="white-space:pre"> </span>cmlmenu = (CircleMenuLayout) findViewById(R.id.cml_menu);
btn = (Button) findViewById(R.id.btn);
cmlmenu.initDatas(titles, imgs);
cmlmenu.setOnMenuItemSelectedListener(new CircleMenuLayout.OnMenuItemSelectedListener() {
@Override
public void onMenuItemOnclick(int code) {
if(code == 0)//
{
Toast.makeText(MainActivity.this, " ", Toast.LENGTH_SHORT).show();
}
else if(code == 1)
{
Toast.makeText(MainActivity.this, " ", Toast.LENGTH_SHORT).show();
}
else if(code == 2)
{
Toast.makeText(MainActivity.this, " ", Toast.LENGTH_SHORT).show();
}
}
});
OK.세 개의 메뉴 회전 효 과 를 완 성 했 습 니 다.위 에서 말 한 것 은 소 편 이 소개 한 안 드 로 이 드 원형 회전 메뉴 개발 사례 입 니 다.여러분 에 게 도움 이 되 기 를 바 랍 니 다.궁금 한 점 이 있 으 면 메 시 지 를 남 겨 주세요.소 편 은 바로 답 해 드 리 겠 습 니 다.여기 서도 저희 사이트 에 대한 여러분 의 지지 에 감 사 드 립 니 다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Kotlin의 기초 - 2부지난 글에서는 Kotlin이 무엇인지, Kotlin의 특징, Kotlin에서 변수 및 데이터 유형을 선언하는 방법과 같은 Kotlin의 기본 개념에 대해 배웠습니다. 유형 변환은 데이터 변수의 한 유형을 다른 데이터...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.