Android 사용자 정의 컨트롤 스위치 단추 학습 노트 공유
우 리 는 흔히 볼 수 있 는 스위치 버튼 을 볼 수 있다.그러면 분석 해 보 자.
우선:
이것 은 두 장의 그림 으로 구성 되 어 있다.
① 열 리 고 닫 히 는 배경 그림
② 열 림 과 닫 기 를 제어 하기 위 한 미끄럼 버튼
첫 번 째 단계:
클래스 계승 View 를 쓰 고 몇 가지 방법 을 다시 쓰 십시오.
첫 번 째 는 구조 함수 입 니 다.매개 변수의 함수 와 두 매개 변수의 함 수 를 다시 쓰 면 됩 니 다.두 매개 변수의 함수 가 사용자 정의 속성 을 사용 할 수 있 기 때 문 입 니 다.
두 번 째 는 컨트롤 의 크기 를 제어 하 는 C>proctected void onMeasure(int width MeasureSpec,int height MeasureSpec){}
세 번 째 는 컨트롤 을 그 리 는 방법 C>proctected void onDraw(Canvas canvas){}
두 번 째 단계:
사용자 가 지정 한 두 장의 그림 을 불 러 옵 니 다.사용자 정의 속성 을 사용 하여 불 러 옵 니 다.values 디 렉 터 리 에 새 attrs.xml 를 만 들 고 xml 파일 에 사용자 정의 속성 이름과 사용자 정의 속성의 필드 와 값 형식(즉 배경 그림 과 슬라이더 그림)을 지정 하면 됩 니 다.
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="switchView_attrs">
<attr name="background" format="reference"></attr>
<attr name="slide" format="reference"></attr>
</declare-styleable>
</resources>
각 필드 의 의 미 는 여기 서 말 하지 않 겠 습 니 다.모 르 는 것 은 앞의 몇 편 을 보 세 요.잘 쓰 면 구조 함수 에 불 러 오기 만 하면 됩 니 다.
public SwitchView(Context context, AttributeSet attrs) {
super(context, attrs);
//
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.switchView_attrs);
//
Drawable switchBackground = ta.getDrawable(R.styleable.switchView_attrs_background);
Drawable switchView_slide = ta.getDrawable(R.styleable.switchView_attrs_slide);
//
backgroundBitmap = convertDrawable2BitmapSimple(switchBackground);
switchSlide = convertDrawable2BitmapSimple(switchView_slide);
}
그러나 주의해 야 할 것 은:사용자 정의 속성 에서 찾 은 것 은 Drawable 대상 이 고 우리 가 원 하 는 것 은 Bitmap 대상 이기 때문에 우 리 는 먼저 Drawable 대상 을 Bitmap 대상 으로 바 꿔 야 합 니 다.사실은 여러 가지 방법 이 있 습 니 다.여기 서 가장 간단 한 방법 을 소개 합 니 다.BitmapDrawable 류 를 통 해:
// Drawable Bitmap
public Bitmap convertDrawable2BitmapSimple(Drawable drawable) {
BitmapDrawable bd= (BitmapDrawable)drawable;
return bd.getBitmap();
}
세 번 째 단계:onMeasure 방법 으로 컨트롤 의 크기 를 조절 할 수 있 습 니 다.이 스위치 버튼 의 크기 는 배경 크기 만큼 크 고 배경 크기 로 만 설정 할 수 있 습 니 다.
//
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (backgroundBitmap != null) {
//
setMeasuredDimension(backgroundBitmap.getWidth(), backgroundBitmap.getHeight());
}else {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
네 번 째 단계:이 스위치 단 추 는 클릭 이나 이동 을 통 해 컨트롤 의 개폐 와 닫 기 를 제어 해 야 하기 때문에 onTouch Event 방법 을 실현 해 야 합 니 다.물론 세 가지 이벤트 가 발생 해 야 합 니 다.누 르 고 이동 하 며 들 어 올 릴 때 클릭,이동 또는 들 어 올 릴 때마다 다시 그 려 야 합 니 다.슬라이더 의 상태 가 어떤(네 가지 상태 가 있어 야 합 니 다)처음에 기본 상태 가 비어 있 는 지 분석 해 보 겠 습 니 다.
1.클릭 할 때
2.이동 할 때
3.들 때
4.비 었 을 때(즉 아무것도 하지 않 았 을 때)
먼저 클릭 할 때의 상황 을 분석 합 니 다.
① 누 르 거나 움 직 이 는 좌표 가 슬라이더 너비 의 절반 이상 일 때 슬라이더 를 오른쪽으로 이동
② 누 르 거나 움 직 이 는 좌표 가 슬라이더 너비 의 절반 이하 일 때 슬라이더 가 움 직 이지 않 는 다.
주:슬라이더 가 배경 밖으로 이동 하 는 것 을 방지 합 니 다.최대 슬라이더 오른쪽 과 배경 오른쪽 정렬(즉,최대 왼쪽 에서 배경 너비-슬라이더 너비)
다시 한 번 이동 할 때의 상황 을 보면 클릭 할 때 와 같 을 것 이다.
다시 들 어 올 릴 때의 상황 을 분석한다.
① 스위치 상태 가 켜 져 있 으 면 슬라이더 를 오른쪽으로 이동
② 스위치 상태 가 꺼 져 있 으 면 슬라이더 를 왼쪽으로 이동
그럼 언제 열 린 상태 와 닫 힌 상태 인지 어떻게 판단 하나 요?
① 들 어 올 린 좌표 가 배경 너비 의 절반 이상 일 때 열 린 상태 로 설정
② 들 어 올 린 좌 표 는 배경 너비 좌표 의 절반 이하 일 때 닫 힌 상태 로 설정
다시 한 번 빈 곳 을 분석 해 보면 들 었 을 때의 상황 과 같다 는 것 을 알 수 있다.
다섯 번 째 단계:
onDraw 방법 에서 배경 과 슬라이더 를 그립 니 다.방금 onTouchEvent 방법 을 분 석 했 는데 이번 에는 똑 같 습 니 다.슬라이더 의 네 가지 상 태 를 각각 처리 하고 앞의 onTouchEvent 방법 에서 슬라이더 의 상태 가 바 뀌 었 습 니 다.그리고 invalidate()방법 을 통 해 시스템 에 다시 그 리 는 것 을 알 립 니 다.
여섯 번 째 단계:
이 사용자 정의 컨트롤 을 만 드 는 것 은 사용자 가 사용 할 수 있 도록 하 는 것 입 니 다.지금 은 아무 소 용이 없습니다.사용자 가 사용 할 수 없 기 때문에 모니터 를 설정 하여 외부 에 인 터 페 이 스 를 제공 할 수 있 습 니 다.
/**
* switchView
*
* */
interface OnSwitchChangedListener {
public void onSwitchChange(boolean isOpen);
}
/**
* switchView
* */
public void setOnChangeListener(OnSwitchChangedListener listener) {
switchListener = listener;
}
이 모니터 의 boolean 값 은 할당 이 필요 합 니 다.언제 할당 할 까요?올 리 거나 비 어 있 을 때 할당 해 야 합 니 다.그 때 는 스위치 버튼 이 열 렸 는 지 닫 혔 는 지 확인 할 수 있 기 때 문 입 니 다.일곱 번 째 단계:
이 단 계 는 레이아웃 파일 에서 사용자 정의 컨트롤 을 정의 하 는 데 사 용 됩 니 다.
<com.example.custom.SwitchView
minguo:background="@drawable/switch_background"
minguo:slide="@drawable/slide_button_background"
android:id="@+id/switchView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
정 의 된 View 를 사용 하면 모두 사용 할 수 있 을 것 입 니 다.아 닙 니 다.'안 드 로 이 드 개발 노트 의 사용자 정의 조합 컨트롤'을 보 세 요.
핵심 코드:
레이아웃 파일
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:minguo="http://schemas.android.com/apk/res/com.example.custom"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.custom.MainActivity" >
<com.example.custom.SwitchView
minguo:background="@drawable/switch_background"
minguo:slide="@drawable/slide_button_background"
android:id="@+id/switchView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
사용자 정의 보기:SwitchView.자바
/**
*
* @author Administrator
*
*/
public class SwitchView extends View {
//
private Bitmap backgroundBitmap,switchSlide;
//
private Paint paint;
// x ( 、 、 )
private float currentX;
//
private boolean isOpen = false;
//
private OnSwitchChangedListener switchListener;
//
public static final int STATE_DOWN = 1; //
public static final int STATE_MOVE = 2; //
public static final int STATE_UP = 3; //
public static final int STATE_NONE = 0; // ( )
// ( )
private int state = STATE_NONE;
public SwitchView(Context context) {
super(context,null);
}
public SwitchView(Context context, AttributeSet attrs) {
super(context, attrs);
//
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.switchView_attrs);
//
Drawable switchBackground = ta.getDrawable(R.styleable.switchView_attrs_background);
Drawable switchView_slide = ta.getDrawable(R.styleable.switchView_attrs_slide);
//
backgroundBitmap = convertDrawable2BitmapSimple(switchBackground);
switchSlide = convertDrawable2BitmapSimple(switchView_slide);
}
// Drawable Bitmap
public Bitmap convertDrawable2BitmapSimple(Drawable drawable) {
BitmapDrawable bd = (BitmapDrawable)drawable;
return bd.getBitmap();
}
//
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (backgroundBitmap != null) {
//
setMeasuredDimension(backgroundBitmap.getWidth(), backgroundBitmap.getHeight());
}else {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
//
@Override
protected void onDraw(Canvas canvas) {
//
if (backgroundBitmap != null) {
paint = new Paint();
// Bitmap
// Bitmap
// Bitmap
//
canvas.drawBitmap(backgroundBitmap, 0, 0, paint);
}
switch (state) {
case STATE_DOWN: // ,
case STATE_MOVE:
//
if (currentX > switchSlide.getWidth()/2f) {
// ( )
float left = currentX - switchSlide.getWidth()/2f;
// , ( - )
float maxLeft = backgroundBitmap.getWidth() - switchSlide.getWidth();
if (left > maxLeft) {
left = maxLeft;
}
canvas.drawBitmap(switchSlide, left, 0, paint);
//
}else if (currentX < switchSlide.getWidth()/2f) {
//
canvas.drawBitmap(switchSlide, 0, 0, paint);
}
break;
case STATE_NONE: //
case STATE_UP:
// ,
if (isOpen) {
if (switchListener != null) {
switchListener.onSwitchChange(true);
}
canvas.drawBitmap(switchSlide,
backgroundBitmap.getWidth() - switchSlide.getWidth(), 0, paint);
// ,
}else {
if (switchListener != null) {
switchListener.onSwitchChange(false);
}
canvas.drawBitmap(switchSlide, 0, 0, paint);
}
break;
default:
break;
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
currentX = event.getX();
//
state = STATE_DOWN;
//
invalidate();//
// postInvalidate();//
break;
case MotionEvent.ACTION_MOVE:
currentX = event.getX();
//
state = STATE_MOVE;
invalidate();
break;
case MotionEvent.ACTION_UP:
currentX = event.getX();
//
state = STATE_UP;
//
if (currentX > backgroundBitmap.getWidth()/2f) {
// ,
isOpen = true;
//
}else if (currentX < backgroundBitmap.getWidth()) {
// ,
isOpen = false;
}
invalidate();
break;
}
return true;
}
/**
* switchView
*
* */
interface OnSwitchChangedListener {
public void onSwitchChange(boolean isOpen);
}
/**
* switchView
* */
public void setOnChangeListener(OnSwitchChangedListener listener) {
switchListener = listener;
}
}
MainActivity.java
public class MainActivity extends Activity {
private SwitchView switchView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
switchView = (SwitchView) findViewById(R.id.switchView);
switchView.setOnChangeListener(new OnSwitchChangedListener() {
@Override
public void onSwitchChange(boolean isOpen) {
if (isOpen) {
//
Toast.makeText(MainActivity.this, " ", Toast.LENGTH_LONG).show();
}else {
//
Toast.makeText(MainActivity.this, " ", Toast.LENGTH_LONG).show();
}
}
});
}
}
여러분 들 은 이렇게 간단 해 보 입 니 다.하 나 는 이렇게 많이 썼 습 니 다.사실은 우리 가 이것 을 배 우 는 것 은 이것 을 쓰기 위해 서가 아니 라 이것 보다 좋 은 기원 이 많은 것 은 이런 사고 와 사 고 를 배우 기 위해 서 입 니 다.여러분 들 은 빨리 해 보 세 요!읽 어 주 셔 서 감사합니다. 저희 의 더 많은 멋 진 내용 도 계속 지 켜 봐 주 셨 으 면 좋 겠 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Bitrise에서 배포 어플리케이션 설정 테스트하기이 글은 Bitrise 광고 달력의 23일째 글입니다. 자체 또는 당사 등에서 Bitrise 구축 서비스를 사용합니다. 그나저나 며칠 전 Bitrise User Group Meetup #3에서 아래 슬라이드를 발표했...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.