ArcMenu
54124 단어 android
사용자 정의 속성//attr.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- -->
<!-- -->
<attr name="position">
<enum name="left_top" value="0" />
<enum name="left_bottom" value="1" />
<enum name="right_top" value="2" />
<enum name="right_bottom" value="3" />
</attr>
<!-- -->
<attr name="radius" format="dimension" />
<!-- -->
<declare-styleable name="ArcMenu">
<attr name="position" />
<attr name="radius" />
</declare-styleable>
</resources>
테스트 읽 기 속성:사용자 정의 컨트롤,사용자 정의 속성 사용
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:myapp="http://schemas.android.com/apk/res/com.example.hendry_arcmenu"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<com.example.hendry_arcmenu.view.ArcMenu
android:id="@+id/id_arcmenu"
android:layout_width="match_parent"
android:layout_height="match_parent"
myapp:position="right_top"
myapp:radius="200sp" >
</com.example.hendry_arcmenu.view.ArcMenu>
</RelativeLayout>
구조 함수 에서 속성 읽 기/ArcMenu.xml
public ArcMenu(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray a = context.getTheme().obtainStyledAttributes(attrs,
R.styleable.ArcMenu, defStyleAttr, 0);
int default_radius = (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_SP, 100, context.getResources()
.getDisplayMetrics());
// mRadius = a.getDimensionPixelSize(R.styleable.ArcMenu_radius,
// default_radius);
mRadius = (int) a.getDimension(R.styleable.ArcMenu_radius, default_radius);
int pos = a.getInt(R.styleable.ArcMenu_position, RIGHT_BOTTOM);
switch (pos) {
case LEFT_TOP:
mPosition = position.LEFT_TOP;
break;
case LEFT_BOTTOM:
mPosition = position.LEFT_BOTTOM;
break;
case RIGHT_TOP:
mPosition = position.RIGHT_TOP;
break;
case RIGHT_BOTTOM:
mPosition = position.RIGHT_BOTTOM;
break;
}
a.recycle();
Log.i("hendry_arcmenu__", "position:" + mPosition + " radius:"
+ mRadius);
}
OnMeasure 는 서브 View 의 너비 와 높이 를 측정 하고 컨트롤 자체 의 너비 와 높이 를 설정 합 니 다.
일반적으로 사용자 정의 view 는
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
이 문장 만 호출 하면 됩 니 다.onMeasure 는 이 사용자 정의 컨트롤 이 레이아웃 파일 에 설 치 된 설정 에 따라 너비 와 높이 를 확인 합 니 다.ViewGroup 을 사용자 정의 하려 면 각 하위 view 를 측정 해 야 합 니 다.
측정 하기 전에 이 컨트롤 의 레이아웃 파일 을 작성 해 야 합 니 다.이 컨트롤 내부 에 어떤 하위 view 가 있 는 지 확인 해 야 측정 을 시작 할 수 있 습 니 다.하위 view 는 그림 자원 등 을 사용 하여 해당 디 렉 터 리 에 복사 해 야 합 니 다.
이 ArcMenu 컨트롤 은 다른 컨트롤 위 에 덮 여 있 으 며 화면의 4 개의 뿔 에 놓 을 수 있 기 때문에 전체 화면 컨트롤 입 니 다.레이아웃 파일 의 너비 와 높이 는 match 로 설정 되 어 있 습 니 다.parent
첫 번 째 메 인 단 추 는 바깥 테두리+내부 에 있 는 그림 을 조합 한 것 입 니 다.그림 회전 애니메이션 을 편리 하 게 하기 위해 서 입 니 다.메 인 단 추 를 제외 하고 다른 단 추 는 모두 그림 상자 ImageView 입 니 다.
복사 onMeasure 방법 은 최종 적 으로 부모 류 set Measured Dimension 방법 을 호출 하거나 우리 가 복사 할 때 전달 폭 이 높 고 set Measured Dimension 방법 을 호출 합 니 다.이 방법 은 전달 하 는 매개 변 수 를 mMeasured Width,mMeasured Height 에 부여 하 는 것 이 주요 역할 입 니 다.즉,우리 가 사용자 정의 컨트롤 의 너비 와 높이 를 확정 한 것 입 니 다.그래서 onMeasure 방법 이 실 행 된 후에...우 리 는 getMeasured Width,getMeasured Height 방법 으로 사용자 정의 컨트롤 을 측정 하여 얻 은 너비 와 높이 를 얻 을 수 있 습 니 다.
viewgroup 의 경우 모든 하위 view 에 measure Child 방법 을 옮 겨 다 녀 야 합 니 다.매개 변 수 는 똑 같 습 니 다.모두 widthMeasure Spec 과 height Measure Spec 입 니 다.이때 measure Child 방법 에 서 는 전 달 된 Measure Spec 매개 변수 에 따라 하위 view 에 대응 하 는 child WidthMeasure Spec 과 child Height Measure Spec 를 생 성 하기 때 문 입 니 다.그리고 child.measure(childWidthMeasureSpec,childHeightMeasureSpec)를 호출 합 니 다.이 방법 은 매우 복잡 해 보이 는데 모두 MeasureSpec 에 대한 계산 이 고 cache 도 있 지만 결국은 set Measured Dimension 방법 을 사용 하여 이 하위 view 의 너비 와 높이 를 설정 합 니 다.
이 를 통 해 알 수 있 듯 이 MeasureSpec 은 중간 변수 와 같 습 니 다.측정 에 필요 한 데 이 터 를 전달 하 는 데 주요 역할 을 합 니 다.32 비트 의 int 값 이 고 높 은 2 비트 는 SpecMode 측정 모델 을 대표 하 며 낮은 30 비트 는 SpecSize 를 대표 합 니 다.특정한 측정 모델 에서 의 규격 크기 를 말 합 니 다.
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int count = getChildCount();
for (int i = 0; i < count; i++) {
// ??? , measureChild MeasureSpec
// getChildAt(i).measure(widthMeasureSpec, heightMeasureSpec);
measureChild(getChildAt(i), widthMeasureSpec, heightMeasureSpec);
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
onLayout
onLayout 는 layot 를 먼저 말 해 야 합 니 다.layot 방법 은 컨트롤 자체 의 위 치 를 확인 하 는 것 이 고 layot 방법 에 서 는 onLayout 방법 을 사용 하여 하위 요소 의 위 치 를 확인 합 니 다.
따라서 사용자 정의 ViewGroup 은 하위 요소 의 위 치 를 확인 하기 위해 onLayout 를 다시 써 야 합 니 다.시스템 은 layot 방법 을 자동 으로 호출 하여 다시 쓴 onLayout 가 호출 됩 니 다.
onLayout 의 기능 은 부모 용기 에서 하위 요소 의 위 치 를 확인 하 는 것 입 니 다.View 와 ViewGroup 은 모두 onLayout 방법 을 진정 으로 실현 하지 못 했 습 니 다.사용자 정의 컨트롤 서브 view 위치 가 확실 하지 않 기 때문에 사용자 정의 로 위 치 를 확인 해 야 합 니 다.따라서 계승 하 는 ViewGroup 이 라면 onLayout 를 복사 할 때 슈퍼.onLayout 방법 을 호출 하 는 것 은 존재 하지 않 습 니 다.스스로 onLayout 를 실현 해 야 합 니 다.onLayout 방법 에서 layot 방법 을 호출 하여 하위 view 에 위 치 를 지정 합 니 다.
모든 View 컨트롤 이 onLayout 를 실현 하지 못 한 것 은 아 닙 니 다.예 를 들 어 사용자 정의 컨트롤 이 Horizontal ScrollView 에서 계승 되면 부모 클래스 의 onLayout
super.onLayout(changed, l, t, r, b);
를 호출 해 야 합 니 다.방금 말 했 듯 이 onLayout 방법 은 최종 적 으로 View.layot 방법 을 호출 하여 하위 view 위 치 를 확인 해 야 합 니 다.onLayout 방법 이 호출 된 이 유 는 View.layot 방법 에서 change 를 판단 하고 onLayout(changed,l,t,r,b)를 다시 호출 하기 때 문 입 니 다.
결국 View.layot 방법 은 컨트롤 에 위 치 를 정 합 니 다.이 컨트롤 에 하위 컨트롤 이 있 으 면 이 컨트롤 의 onLayout 방법 을 호출 합 니 다.onLayout 방법 은 중성자 컨트롤 이 자신의 layot 방법 을 호출 합 니 다.하위 컨트롤 아래 에 하위 컨트롤 이 있 으 면 layot 방법 이 호출 될 때 changed 변 수 를 검사 하고 해당 하 는 onLayout 를 실행 하여 하위 view 를 찾 습 니 다.그래서 이렇게 층 층 이 전달 된다.
이 를 통 해 알 수 있 듯 이 View.layot 방법 은 먼저 컨트롤 자체 에 대한 포 지 셔 닝 을 한 다음 onLayout 를 호출 하여 하위 컨트롤 에 대한 포 지 셔 닝 을 합 니 다.onLayout 실행 과정 에서 하위 컨트롤 에 대응 하 는 layot 방법 을 호출 합 니 다.layot 실행 중 하위 컨트롤 에 하위 컨트롤 이 있 는 것 을 발견 하면 onLayout 를 호출 하여 하위 컨트롤 을 확인 합 니 다.
다시 말 하면 우리 가 다시 쓴 View Group 의 onLayout 를 호출 할 때 우리 가 해 야 할 일 은 하위 요 소 를 옮 겨 다 니 며 layot 방법 을 호출 하 는 것 입 니 다.만약 에 이 하위 요소 아래 에 하위 요소 가 있다 면 onLayout 방법 을 다시 호출 하 는 것 입 니 다.이렇게 view 아래 의 하위 view 는 포 지 셔 닝 을 받 았 습 니 다.또한 View Group 은 원래 onLayout 를 제공 하지 않 았 습 니 다.우리 가 복사 한 onLayout 는 View Group 의 View.layot 가 실행 되 었 기 때문에 복사 한 onLayout 가 호출 되 었 습 니 다.따라서 슈퍼.onLayout()가 없 으 면 view Group 의 포 지 셔 닝 이 실행 되 지 않 아 도 됩 니 다.
android.view.View.layout(int l, int t, int r, int b)
4 개의 매개 변 수 는 left,top,right,bottom 에 대응 하 는 것 이 보통
mCButton.layout(l, t, l + width, t + width);
입 니 다.//attr.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- -->
<!-- -->
<attr name="position">
<enum name="left_top" value="0" />
<enum name="left_bottom" value="1" />
<enum name="right_top" value="2" />
<enum name="right_bottom" value="3" />
</attr>
<!-- -->
<attr name="radius" format="dimension" />
<!-- -->
<declare-styleable name="ArcMenu">
<attr name="position" />
<attr name="radius" />
</declare-styleable>
</resources>
//activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:myapp="http://schemas.android.com/apk/res/com.example.hendry_arcmenu" android:layout_width="match_parent" android:layout_height="match_parent" >
<ListView android:id="@+id/id_listview" android:layout_width="match_parent" android:layout_height="match_parent" >
</ListView>
<com.example.hendry_arcmenu.view.ArcMenu android:id="@+id/id_arcmenu" android:layout_width="match_parent" android:layout_height="match_parent" myapp:position="left_bottom" myapp:radius="120dp" >
<RelativeLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/composer_button" >
<ImageView android:id="@+id/id_button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:src="@drawable/composer_icn_plus" />
</RelativeLayout>
<ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/composer_music" android:tag="Music" />
<ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/composer_place" android:tag="Place" />
<ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/composer_sleep" android:tag="Sleep" />
<ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/composer_thought" android:tag="Sun" />
<ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/composer_with" android:tag="People" />
</com.example.hendry_arcmenu.view.ArcMenu>
</RelativeLayout>
//MainActivity.java
package com.example.hendry_arcmenu;
import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;
import com.example.hendry_arcmenu.view.ArcMenu;
import com.example.hendry_arcmenu.view.ArcMenu.OnMenuItemClickListener;
public class MainActivity extends Activity {
private ListView mListView;
private ArcMenu mArcMenu;
private List<String> mData;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initData();
initViews();
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, mData);
mListView.setAdapter(adapter);
initEvents();
}
private void initEvents() {
// ListView arcMenu
mListView.setOnScrollListener(new OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
// TODO Auto-generated method stub
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
if (mArcMenu.isOpen()) {
mArcMenu.toggleMenu(600);
}
}
});
// arcMenu
mArcMenu.setOnMenuItemClickListener(new OnMenuItemClickListener() {
@Override
public void onClick(View view, int pos) {
Toast.makeText(
MainActivity.this,
"you clicked item getTag: " + view.getTag() + " , pos:"
+ pos, Toast.LENGTH_SHORT).show();
}
});
}
private void initViews() {
mListView = (ListView) findViewById(R.id.id_listview);
mArcMenu = (ArcMenu) findViewById(R.id.id_arcmenu);
}
private void initData() {
mData = new ArrayList<String>();
// char
for (int i = 'A'; i < 'Z'; i++) {
mData.add((char) i + " "); // char
}
}
}
ArcMenu 에 잘 모 르 는 것 이 있 습 니 다.바로 onLayout 에 child.setVisibility(View.GONE)가 설치 되 어 있 는 것 을 제외 하고.이 곳 을 제외 하고 하위 메뉴 항목 을 숨 길 수 있 습 니 다.애니메이션 을 설정 할 때 메뉴 애니메이션 을 닫 고 child.setVisibility 를 GONE 로 설정 하면 소 용이 없습니다.toggleMenu 에 서 는 처음부터 childView 를 설정 합 니 다.setVisibility(View.VISIBLE);여기 주석 이 떨어져 도 아무런 영향 이 없 는데..................................................
onLayout 설정 을 숨 긴 후 애니메이션 의 setFillAfter 설정 으로 만 하위 메뉴 항목 이 표시 되 는 지 여 부 를 제어 할 수 있 습 니 다.setVisibility 는 적용 되 지 않 습 니 다.그러나 원래 코드 를 보면 이 방법 이 아니 라 setVisibility 로 하위 메뉴 항목 이 표시 되 는 지 여 부 를 제어 할 수 있 습 니 다.
//ArcMenu.java
package com.example.hendry_arcmenu.view;
import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.util.Log;
import android.util.TypedValue;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.view.animation.AlphaAnimation;
import android.view.animation.AnimationSet;
import android.view.animation.RotateAnimation;
import android.view.animation.ScaleAnimation;
import android.view.animation.TranslateAnimation;
import com.example.hendry_arcmenu.R;
public class ArcMenu extends ViewGroup implements OnClickListener {
/** * */
private enum position {
LEFT_TOP, LEFT_BOTTOM, RIGHT_TOP, RIGHT_BOTTOM
};
private static final int LEFT_TOP_VAL = 0;
private static final int LEFT_BOTTOM_VAL = 1;
private static final int RIGHT_TOP_VAL = 2;
private static final int RIGHT_BOTTOM_VAL = 3;
private int mRadius;
private position mPosition = position.RIGHT_BOTTOM;
private enum status {
OPEN, CLOSED
};
private status mStatus = status.CLOSED;
private OnMenuItemClickListener mMenuItemClickListener;
/** * */
public interface OnMenuItemClickListener {
void onClick(View view, int pos);
}
public void setOnMenuItemClickListener(OnMenuItemClickListener listener) {
mMenuItemClickListener = listener;
}
public ArcMenu(Context context) {
this(context, null);
}
public ArcMenu(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public ArcMenu(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray a = context.getTheme().obtainStyledAttributes(attrs,
R.styleable.ArcMenu, defStyleAttr, 0);
int default_radius = (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_SP, 100, context.getResources()
.getDisplayMetrics());
// mRadius = a.getDimensionPixelSize(R.styleable.ArcMenu_radius,
// default_radius);
mRadius = (int) a.getDimension(R.styleable.ArcMenu_radius,
default_radius);
int pos = a.getInt(R.styleable.ArcMenu_position, RIGHT_BOTTOM_VAL);
switch (pos) {
case LEFT_TOP_VAL:
mPosition = position.LEFT_TOP;
break;
case LEFT_BOTTOM_VAL:
mPosition = position.LEFT_BOTTOM;
break;
case RIGHT_TOP_VAL:
mPosition = position.RIGHT_TOP;
break;
case RIGHT_BOTTOM_VAL:
mPosition = position.RIGHT_BOTTOM;
break;
}
a.recycle();
Log.i("hendry_arcmenu__", "position:" + mPosition + " radius:"
+ mRadius);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int count = getChildCount();
for (int i = 0; i < count; i++) {
// ??? , measureChild MeasureSpec
// getChildAt(i).measure(widthMeasureSpec, heightMeasureSpec);
measureChild(getChildAt(i), widthMeasureSpec, heightMeasureSpec);
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
if (changed) {
layoutCButton();
//
int count = getChildCount();
for (int i = 0; i < count - 1; i++) {
// i + 1 ,
View child = getChildAt(i + 1);
//
child.setVisibility(View.GONE);
// left, top
int cl = (int) (mRadius * Math.sin(i
* (Math.PI / 2 / (count - 2))));
int ct = (int) (mRadius * Math.cos(i
* (Math.PI / 2 / (count - 2))));
int cWidth = child.getMeasuredWidth();
int cHeight = child.getMeasuredHeight();
switch (mPosition) {
case LEFT_TOP:
break;
case LEFT_BOTTOM:
ct = getMeasuredHeight() - ct - cHeight;
break;
case RIGHT_TOP:
cl = getMeasuredWidth() - cl - cWidth;
break;
case RIGHT_BOTTOM:
cl = getMeasuredWidth() - cl - cWidth;
ct = getMeasuredHeight() - ct - cHeight;
break;
}
child.layout(cl, ct, cl + cWidth, ct + cHeight);
}
}
}
private void layoutCButton() {
// CButton
View CButton = getChildAt(0);
// CButton
CButton.setOnClickListener(this);
//
int width = CButton.getMeasuredWidth();
int height = CButton.getMeasuredHeight();
//
int l = 0;
int t = 0;
switch (mPosition) {
case LEFT_TOP:
l = 0;
t = 0;
break;
case LEFT_BOTTOM:
l = 0;
// getMeasuredHeight getMeasuredWidth
t = getMeasuredHeight() - height;
break;
case RIGHT_TOP:
l = getMeasuredWidth() - width;
t = 0;
break;
case RIGHT_BOTTOM:
l = getMeasuredWidth() - width;
t = getMeasuredHeight() - height;
break;
}
// layout
CButton.layout(l, t, l + width, t + height);
}
@Override
public void onClick(View v) {
// CButton setOnClickListener , CButton view
rotateCButton(v, 0f, 360f, 300);
toggleMenu(300);
}
/** * view * * @param duration */
public void toggleMenu(int duration) {
int count = getChildCount();
// CButton , , , ,
int margin = ( getChildAt(0).getMeasuredWidth() - getChildAt(1).getMeasuredWidth()) /2 ;
// CButton
// for , ,
for (int i = 0; i < count - 1; i++) {
// view
final View childView = getChildAt(i + 1);
childView.setVisibility(View.VISIBLE);
// , , 0, 0 ,
// mRadius , CButton , ,
int deltaX = (int) (mRadius * Math.sin(i
* (Math.PI / 2 / (count - 2))) - margin);
int deltaY = (int) (mRadius * Math.cos(i
* (Math.PI / 2 / (count - 2))) - margin);
// to open , layout ,
// close , ,
// , X ,
// X , 0
// X , ,
// Y , .. ,
// , , , (-1), (-1), sin, cos
// , X (-1), Y
// X ,Y (-1)
// X ,Y
// 4
int xflag = 1;
int yflag = 1;
switch (mPosition) {
case LEFT_TOP:
xflag = -1;
yflag = -1;
break;
case LEFT_BOTTOM:
xflag = -1;
yflag = 1;
break;
case RIGHT_TOP:
xflag = 1;
yflag = -1;
break;
case RIGHT_BOTTOM:
xflag = 1;
yflag = 1;
break;
}
// TranslateAnimation transAn = null;
Animation transAn = null;
if (mStatus == status.CLOSED) { //
// ,
transAn = new TranslateAnimation(deltaX * xflag, 0, deltaY
* yflag, 0);
//
childView.setFocusable(true);
childView.setClickable(true);
} else { //
// , , , if
transAn = new TranslateAnimation(0, deltaX * xflag, 0, deltaY
* yflag);
// , , , , GONE ,
// , , ,
childView.setClickable(false);
childView.setFocusable(false);
}
transAn.setFillAfter(true);
transAn.setDuration(duration);
//
transAn.setStartOffset((i * 100) / count);
//
RotateAnimation rotateAnim = new RotateAnimation(0, 720,
Animation.RELATIVE_TO_SELF, 0.5f,
Animation.RELATIVE_TO_SELF, 0.5f);
rotateAnim.setDuration(duration);
rotateAnim.setFillAfter(true);
AnimationSet anSet = new AnimationSet(true);
anSet.addAnimation(rotateAnim);
anSet.addAnimation(transAn);
// childView.startAnimation(rotateAnim);
// childView.startAnimation(transAn);
// childView.startAnimation(anSet);
/** * view visibility GONE , */
if (mStatus == status.CLOSED) {
anSet.setFillAfter(true); // animationSet fillAfter
//
} else {
//
AlphaAnimation alphaAni = new AlphaAnimation(1.0f, 0.5f);
anSet.addAnimation(alphaAni);
anSet.setFillAfter(false);
}
anSet.setAnimationListener(new AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
}
@Override
public void onAnimationRepeat(Animation animation) {
}
/** * ? */
@Override
public void onAnimationEnd(Animation animation) {
if (mStatus == status.CLOSED) {
childView.setVisibility(View.GONE);
}
}
});
childView.startAnimation(anSet);
/** * */
final int pos = i + 1; // i + 1 CButton
childView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
//
if (null != mMenuItemClickListener) {
mMenuItemClickListener.onClick(v, pos);
}
// , pos -1 , CButton 0
menuItemAnim(pos - 1);
// ,
changeStatus();
}
});
}
//
changeStatus();
Log.i("MYTAG", "mStatus : " + mStatus);
}
private void changeStatus() {
mStatus = (mStatus == status.CLOSED ? status.OPEN : status.CLOSED);
}
/** * , pos 0 , , */
protected void menuItemAnim(int pos) {
int count = getChildCount();
for (int i = 0; i < count - 1; i++) {
View child = getChildAt(i + 1);
if (pos == i) {
//
child.startAnimation(scaleBigAni(500));
} else {
//
child.startAnimation(scaleSmallAnimation(500,0.0f));
}
//
child.setClickable(false);
child.setFocusable(false);
}
}
private Animation scaleBigAni(int duration) {
AnimationSet animationSet = new AnimationSet(true);
// 4
ScaleAnimation scaleAnim = new ScaleAnimation(1.0f, 4.0f, 1.0f, 4.0f,
Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
0.5f);
//
AlphaAnimation alphaAnim = new AlphaAnimation(1f, 0.0f);
animationSet.addAnimation(scaleAnim);
animationSet.addAnimation(alphaAnim);
animationSet.setDuration(duration);
animationSet.setFillAfter(true);
return animationSet;
}
private Animation scaleSmallAnimation(int duration , float toScale) {
AnimationSet animationSet = new AnimationSet(true);
ScaleAnimation scaleAnim = new ScaleAnimation(1.0f, toScale, 1.0f, toScale,
Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
0.5f);
AlphaAnimation alphaAnim = new AlphaAnimation(1.f, 0.0f);
animationSet.addAnimation(scaleAnim);
animationSet.addAnimation(alphaAnim);
animationSet.setDuration(duration);
animationSet.setFillAfter(true);
return animationSet;
}
private void rotateCButton(View v, float start, float end, int duration) {
RotateAnimation anima = new RotateAnimation(start, end,
Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
0.5f);
anima.setDuration(duration);
anima.setFillAfter(true); //
v.startAnimation(anima);
}
public Boolean isOpen() {
return mStatus == status.OPEN;
}
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Kotlin의 기초 - 2부지난 글에서는 Kotlin이 무엇인지, Kotlin의 특징, Kotlin에서 변수 및 데이터 유형을 선언하는 방법과 같은 Kotlin의 기본 개념에 대해 배웠습니다. 유형 변환은 데이터 변수의 한 유형을 다른 데이터...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.