안 드 로 이 드 모방 바 이 두 복 주머니 보너스 인터페이스
1.프로 그래 밍 사고
화면 을 보면 9 장의 그림 을 넣 은 용기 라 는 것 을 알 수 있 습 니 다.그 위 에 투명 한 View 를 만들어 선과 원 을 그 릴 수 있 습 니 다.다음은 실현 과정 을 소개 하 겠 습 니 다.
사용자 정의 ViewGroup
사용자 정의 ViewGroup 은 onLayout()방법 이 필요 하 다 는 것 을 알 고 있 습 니 다.이 방법 은 하위 View 의 위치 와 사 이 즈 를 설정 할 때 호출 합 니 다.또 하나의 onMeasure()방법 은 view 와 그 내용 을 측정 하여 view 의 너비 와 높이 를 확정 하 는 것 이다.
2.점 과 원 의 위치 및 그리 기 파 라 메 터 를 저장 합 니 다.
다시 인터페이스 로 돌아 갈 때,지난번 그리 기 인터페이스의 내용 을 저장 하지 않 을 것 이 며,다시 그 릴 때 인터페이스 에 저장 해 야 합 니 다
세 가지 간단 한 크기 조정 애니메이션
4 사용자 정의 View 그리 기 인터페이스 구현
5.그림 이 완성 되 었 을 때 화면 에 내용 을 그 리 는 것 을 지우 고 중복 그림 을 연결 하지 않도록 합 니 다.
다음 에 우 리 는 이 절 차 를 완성 할 것 이다.
2.사용자 정의 뷰 그룹
시작 하 는 임 무 는 9 장의 그림 을 그림 의 위치 에 평균 적 으로 분포 하여 휴대 전화 인터페이스 에 표시 하 는 것 이다.그 코드 는 다음 과 같다.
public class LYJViewGroup extends ViewGroup implements LYJGestureDrawline.OnAnimationCallback{
/**
*
*/
private int childWidth;
/***
*
*/
private Context context;
/***
*
*/
private List<LYJGesturePoint> list;
/***
* view ViewGroup 。
*/
private LYJGestureView gestureDrawline;
private int baseNum = 5;
public LYJViewGroup(Context context) {
super(context);
this.context = context;
this.list = new ArrayList<>();
DisplayMetrics metric = new DisplayMetrics();
((Activity) context).getWindowManager().getDefaultDisplay().getMetrics(metric);
childWidth = metric.widthPixels / 3; // ( )
addChild();
// view
gestureDrawline = new LYJGestureView(context, list);
gestureDrawline.setAnimationCallback(this);
}
public void setParentView(ViewGroup parent){
//
DisplayMetrics metric = new DisplayMetrics();
((Activity) context).getWindowManager().getDefaultDisplay().getMetrics(metric);
int width = metric.widthPixels;
LayoutParams layoutParams = new LayoutParams(width, width);
this.setLayoutParams(layoutParams);
gestureDrawline.setLayoutParams(layoutParams);
parent.addView(this);
parent.addView(gestureDrawline);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
for (int i = 0; i < getChildCount(); i++) {
//
int rowspan = i / 3;
//
int column = i % 3;
android.view.View v = getChildAt(i);
v.layout(column * childWidth + childWidth / baseNum, rowspan * childWidth + childWidth / baseNum,
column * childWidth + childWidth - childWidth / baseNum, rowspan * childWidth + childWidth - childWidth / baseNum);
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
// view
for (int i = 0; i < getChildCount(); i++) {
View v = getChildAt(i);
v.measure(widthMeasureSpec, heightMeasureSpec);
}
}
private void addChild() {
for (int i = 0; i < 9; i++) {
ImageView image = new ImageView(context);
image.setBackgroundResource(R.drawable.marker);
this.addView(image);
invalidate();
//
int rowspan = i / 3;
//
int column = i % 3;
//
int leftX = column * childWidth + childWidth / baseNum;
int topY = rowspan * childWidth + childWidth / baseNum;
int rightX = column * childWidth + childWidth - childWidth / baseNum;
int bottomY = rowspan * childWidth + childWidth - childWidth / baseNum;
LYJGesturePoint p = new LYJGesturePoint(leftX, topY, rightX,bottomY,i);
this.list.add(p);
}
}
@Override
public void startAnimationImage(int i) {
Animation animation= AnimationUtils.loadAnimation(getContext(), R.anim.gridlayout_child_scale_anim);
getChildAt(i).startAnimation(animation);
}
}
3.사용자 정의 점 클래스말 그대로 점 과 관련 된 속성 을 얻 기 위해 서 입 니 다.그 중에서 기본 속성 이미지 왼쪽 상단 좌표 와 오른쪽 아래 좌 표를 계산 하여 이미지 중심 점 을 얻 을 수 있 습 니 다.상태 표 시 는 이 점 이 그림 에 그 려 질 지 여 부 를 표시 합 니 다.다음은 그 실체 클래스 입 니 다.
public class LYJGesturePoint {
private Point pointLeftTop;//
private Point pointRightBottom;//
private int centerX;// X
private int centerY;// Y
private int pointState;//
private int num;
public int getNum() {
return num;
}
public int getPointState() {
return pointState;
}
public void setPointState(int pointState) {
this.pointState = pointState;
}
public Point getPointLeftTop() {
return pointLeftTop;
}
public Point getPointRightBottom() {
return pointRightBottom;
}
public LYJGesturePoint(int left,int top,int right,int bottom,int i){
this.pointLeftTop=new Point(left,top);
this.pointRightBottom=new Point(right,bottom);
this.num=i;
}
public int getCenterX() {
this.centerX=(this.pointLeftTop.x+this.pointRightBottom.x)/2;
return centerX;
}
public int getCenterY() {
this.centerY=(this.pointLeftTop.y+this.pointRightBottom.y)/2;
return centerY;
}
}
4.사용자 정의 원류이 종 류 는 비교적 간단 하고 세 가지 속성 일 뿐(원 중심 점 좌표 와 반지름)코드 는 다음 과 같다.
public class LYJCirclePoint {
private int roundX;// X
private int roundY;// Y
private int radiu;//
public int getRadiu() {
return radiu;
}
public int getRoundX() {
return roundX;
}
public int getRoundY() {
return roundY;
}
public LYJCirclePoint(int roundX,int roundY,int radiu){
this.roundX=roundX;
this.roundY=roundY;
this.radiu=radiu;
}
}
5.사용자 정의 그리 기 클래스 View 구현코드 는 다음 과 같 습 니 다:
public class LYJGestureView extends android.view.View {
/***
*
*/
private Paint paint;
/***
*
*/
private Paint circlePaint;
/***
*
*/
private Canvas canvas;
/***
*
*/
private Bitmap bitmap;
/***
* view ,
*/
private List<LYJGesturePoint> list;
/***
*
*/
private List<Pair<LYJGesturePoint, LYJGesturePoint>> lineList;
/***
*
*/
private List<LYJCirclePoint> circlePoints;
/**
* Point
*/
private LYJGesturePoint currentPoint;
/***
*
*/
private OnAnimationCallback animationCallback;
public interface OnAnimationCallback{
public void startAnimationImage(int i);
}
public void setAnimationCallback(OnAnimationCallback animationCallback) {
this.animationCallback = animationCallback;
}
public LYJGestureView(Context context, List<LYJGesturePoint> list){
super(context);
Log.i(getClass().getName(), "GestureDrawline");
paint = new Paint(Paint.DITHER_FLAG);//
circlePaint=new Paint(Paint.DITHER_FLAG);
DisplayMetrics metric = new DisplayMetrics();
((Activity)context).getWindowManager().getDefaultDisplay().getMetrics(metric);
Log.i(getClass().getName(), "widthPixels" + metric.widthPixels);
Log.i(getClass().getName(), "heightPixels" + metric.heightPixels);
bitmap = Bitmap.createBitmap(metric.widthPixels, metric.heightPixels, Bitmap.Config.ARGB_8888); //
canvas = new Canvas();
canvas.setBitmap(bitmap);
paint.setStyle(Paint.Style.STROKE);//
paint.setStrokeWidth(20);// 20
paint.setColor(Color.rgb(245, 142, 33));//
paint.setAntiAlias(true);//
circlePaint.setStyle(Paint.Style.FILL);
circlePaint.setStrokeWidth(1);
circlePaint.setAntiAlias(true);
circlePaint.setColor(Color.rgb(245, 142, 33));
this.list = list;
this.lineList = new ArrayList<>();
this.circlePoints=new ArrayList<>();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
//
currentPoint = getPointAt((int) event.getX(), (int) event.getY());
if (currentPoint != null) {
currentPoint.setPointState(Constants.POINT_STATE_SELECTED);
this.animationCallback.startAnimationImage(currentPoint.getNum());
canvas.drawCircle(currentPoint.getCenterX(), currentPoint.getCenterY(), 20, circlePaint);
circlePoints.add(new LYJCirclePoint(currentPoint.getCenterX(),currentPoint.getCenterY(),20));
}
invalidate();
break;
case MotionEvent.ACTION_MOVE:
clearScreenAndDrawList();
//
LYJGesturePoint pointAt = getPointAt((int) event.getX(), (int) event.getY());
if (currentPoint == null && pointAt == null) {// ,
return true;
} else {//
if (currentPoint == null) {// point null
// , currentPoint
currentPoint = pointAt;
// currentPoint ;
currentPoint.setPointState(Constants.POINT_STATE_SELECTED);
}
}
// , ,
if(pointAt == null || currentPoint.equals(pointAt) || Constants.POINT_STATE_SELECTED == pointAt.getPointState()){
canvas.drawCircle(currentPoint.getCenterX(), currentPoint.getCenterY(), 20, circlePaint);
circlePoints.add(new LYJCirclePoint(currentPoint.getCenterX(), currentPoint.getCenterY(), 20));
canvas.drawLine(currentPoint.getCenterX(), currentPoint.getCenterY(), event.getX(), event.getY(), paint);
}else{// , ,
canvas.drawCircle(pointAt.getCenterX(),pointAt.getCenterY(),20,circlePaint);
circlePoints.add(new LYJCirclePoint(pointAt.getCenterX(), pointAt.getCenterY(), 20));
this.animationCallback.startAnimationImage(pointAt.getNum());
pointAt.setPointState(Constants.POINT_STATE_SELECTED);
canvas.drawLine(currentPoint.getCenterX(), currentPoint.getCenterY(), pointAt.getCenterX(), pointAt.getCenterY(), paint);
Pair<LYJGesturePoint, LYJGesturePoint> pair = new Pair<>(currentPoint, pointAt);
lineList.add(pair);
currentPoint=pointAt;// 。
}
invalidate();//
break;
case MotionEvent.ACTION_UP:
clearScreenAndDrawList();//
new Handler().postDelayed(new clearLineRunnable(), 1000);//1
invalidate();//
break;
default:
break;
}
return true;
}
class clearLineRunnable implements Runnable {
public void run() {
//
lineList.clear();
circlePoints.clear();
//
clearScreenAndDrawList();
for (LYJGesturePoint p : list) {
//
p.setPointState(Constants.POINT_STATE_NORMAL);
}
invalidate();
}
}
/**
* Point
*
* @param x
* @param y
* @return , null,
*/
private LYJGesturePoint getPointAt(int x, int y) {
for (LYJGesturePoint point : list) {
// X
int leftX = point.getPointLeftTop().x;
int rightX = point.getPointRightBottom().x;
if (!(x >= leftX && x < rightX)) {
// ,
continue;
}
// Y
int topY = point.getPointLeftTop().y;
int bottomY = point.getPointRightBottom().y;
if (!(y >= topY && y < bottomY)) {
// ,
continue;
}
// ,
return point;
}
return null;
}
/**
* ,
*/
private void clearScreenAndDrawList() {
canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
for (Pair<LYJGesturePoint, LYJGesturePoint> pair : lineList) {
canvas.drawLine(pair.first.getCenterX(), pair.first.getCenterY(),
pair.second.getCenterX(), pair.second.getCenterY(), paint);//
}
for(LYJCirclePoint lyjCirclePoint : circlePoints){
canvas.drawCircle(lyjCirclePoint.getRoundX(),lyjCirclePoint.getRoundY(), lyjCirclePoint.getRadiu(),circlePaint);
}
}
// bitmap
@Override
protected void onDraw(Canvas canvas) {
canvas.drawBitmap(bitmap, 0, 0, null);
}
}
이렇게 하면 다음 과 같은 인터페이스 효 과 를 얻 을 수 있다.이상 이 바로 본문의 전체 내용 입 니 다.여러분 들 이 안 드 로 이 드 를 배 우 는 데 도움 이 되 기 를 바 랍 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 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에 따라 라이센스가 부여됩니다.