畫(huà)板1.0

一、目的

寫(xiě)代碼實(shí)現(xiàn)一個(gè)畫(huà)板效果。


開(kāi)心猿刻

二、知識(shí)點(diǎn)

一、橫豎屏切換設(shè)置:

1.配置文件:

screenOrientation= 意義
"sensor" 隨著屏幕的方向變化而變化
"portrait" 豎屏鎖定
"landscape" 鎖定橫屏(一個(gè)方向)sensorLandscape 2個(gè)方向

2.代碼設(shè)置:onResume里設(shè)置

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_FULLSENSOR);

二、自適應(yīng)布局

整體:ConstraintLayout約束布局:要約束確定的寬高,xy
部件:LinearLayout

三、自定義滑動(dòng)條Slider

1.進(jìn)度條;沒(méi)有thumb小圓點(diǎn),不接收觸摸
2.滑動(dòng)條:有小圓點(diǎn),接收觸摸
1.當(dāng)觸摸時(shí)小圓點(diǎn)放大
2.監(jiān)聽(tīng)滑動(dòng)事件
3.橫豎切換:width>height橫著 width>height 豎著

創(chuàng)建Slider extends View
1.添加約束

<com.example.a16palette.Slider
            android:layout_width="20dp"
            android:layout_height="match_parent"
            android:layout_marginLeft="10dp"
            android:layout_marginTop="10dp"
            android:layout_marginBottom="10dp"/>

進(jìn)度條背景

變量

初始化和onDrow

縱、橫向效果

進(jìn)度條小圓點(diǎn)
函數(shù)

實(shí)現(xiàn)效果

四、滑動(dòng)

變量、函數(shù)
解決:點(diǎn)哪不動(dòng)哪
畫(huà)進(jìn)度條
滑動(dòng)實(shí)現(xiàn)效果

五、外部

樣式:進(jìn)度條 or 滑動(dòng)條選擇

樣式

樣式的set、get方法

進(jìn)度值的交互及在MainActivity里的模擬及max值的設(shè)置
交互-進(jìn)度

交互-max值

六、數(shù)據(jù)回調(diào)

接口.png
監(jiān)聽(tīng).png
callback的實(shí)現(xiàn)和調(diào)用和進(jìn)度條外部問(wèn)題優(yōu)化.png

改正:MotionEvent.ACTION_DOWN處不需要條件的判斷


三、實(shí)際應(yīng)用

今日實(shí)現(xiàn)的最終效果:


11.12的最終效果.png

完整代碼:
activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:orientation="horizontal"
        app:layout_constraintBottom_toTopOf="@+id/operation"
        app:layout_constraintTop_toTopOf="parent">

        <!--滑動(dòng)條-->
        <com.example.a16palette.Slider
            android:id="@+id/slider"
            android:layout_width="20dp"
            android:layout_height="match_parent"
            android:layout_marginLeft="10dp"
            android:layout_marginTop="10dp"
            android:layout_marginBottom="10dp"
            android:layout_marginRight="10dp"/>
    </LinearLayout>

    <LinearLayout
        android:id="@+id/operation"
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:orientation="horizontal"
        app:layout_constraintBottom_toBottomOf="parent"
        android:background="@color/colorAccent">
    </LinearLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

Slider.java(自己創(chuàng)的一個(gè)Class用來(lái)自定義滑動(dòng)條的):有點(diǎn)多,別怕

package com.example.a16palette;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

import androidx.annotation.Nullable;

public class Slider extends View {
    private int lineSize = 4;//線的粗細(xì)
    private Paint linePaint;//線畫(huà)筆
    private int lineColor = Color.GRAY;//默認(rèn)線顏色灰色

    private int centerX;//中心點(diǎn)x
    private int centerY;//中心點(diǎn)y
    private int radius;//小圓點(diǎn)的半徑
    private Paint circlePaint;//畫(huà)圓的畫(huà)筆
    private int thumbColor = Color.MAGENTA;//圓點(diǎn)的顏色

    private int thumbScale = 4;//小圓點(diǎn)縮放倍數(shù)分之一
    private float position;//記錄觸摸點(diǎn)的坐標(biāo)變化值

    private Paint progressPaint;//進(jìn)度條進(jìn)度的畫(huà)筆
    private int progressColor = Color.MAGENTA;//進(jìn)度條顏色

    public static int PROGRESS = 0;//進(jìn)度條
    public static int SLIDER = 1;//滑動(dòng)條
    private int style = PROGRESS;//樣式:進(jìn)度條或滑動(dòng)條

    public int max = 100;//設(shè)置最大值 默認(rèn)100
    public float progress;//進(jìn)度值

    private OnSliderChangeListener onSliderChangeListener;//滑動(dòng)改變的監(jiān)聽(tīng)者

    public Slider(Context context) {
        super(context);
        init();
    }

    public Slider(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    private void init(){
//        setBackgroundColor(Color.BLACK);
        linePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        linePaint.setColor(lineColor);
        linePaint.setStrokeWidth(lineSize);

        circlePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        circlePaint.setColor(thumbColor);
        circlePaint.setStyle(Paint.Style.FILL);

        progressPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        progressPaint.setColor(progressColor);
        progressPaint.setStrokeWidth(lineSize);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        if (getWidth() > getHeight()){
            //橫著
            canvas.drawLine(0,getHeight()/2,getWidth(),getHeight()/2,linePaint);//進(jìn)度條打底
            canvas.drawLine(0,getHeight()/2,position,getHeight()/2,progressPaint);//進(jìn)度條
            radius = getHeight()/thumbScale;
            //X的變化
            if (position < radius){
            centerX = radius;
            }else if (position > getWidth() - radius){
                centerX = getWidth() - radius;
            }
            else {
                centerX = (int) position;
            }
            centerY = getHeight()/2;
//            centerY =getPivotY();

        }else {
            //豎著
            canvas.drawLine(getWidth()/2,0,getWidth()/2,getHeight(),linePaint);//進(jìn)度條打底
            if (position > 0) {
                canvas.drawLine(getWidth() / 2, 0, getWidth() / 2, position, progressPaint);//進(jìn)度條
            }
            radius = getWidth()/thumbScale;
            centerX = getWidth()/2;
            //Y的變化
            if (position < radius){
                centerY = radius;
            }else if (position > getHeight() - radius){
                centerY = getHeight() - radius;
            }else {
                centerY = (int) position;
            }
        }
//        //畫(huà)進(jìn)度條
//        canvas.drawLine();
        //畫(huà)小圓點(diǎn)
        if (style == SLIDER) {
            canvas.drawCircle(centerX, centerY, radius, circlePaint);
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()){
            case MotionEvent.ACTION_DOWN:
                //小圓點(diǎn)放大
                thumbScale = 2;
                if(getHeight()<getWidth()){
                    //橫 X變化
                    position = event.getX();
                    if(position < 0) position =0;//避免點(diǎn)到進(jìn)度條外面仍有x,y值
                    else  if(position > getWidth()) position =getWidth();
                }else {
                    //豎 Y變化
                    position = event.getY();
                    if(position < 0) position =0;
                    else  if(position > getHeight()) position =getHeight();
                }
                callback();
                break;
            case MotionEvent.ACTION_MOVE:
                //獲取當(dāng)前觸摸點(diǎn)的值 XorY
                if(getHeight()<getWidth()){
                    //橫 X變化
                    position = event.getX();
                    if(position < 0) position =0;
                    else  if(position > getWidth()) position =getWidth();
                }else {
                    //豎 Y變化
                    position = event.getY();
                    if(position < 0) position =0;
                    else  if(position > getHeight()) position =getHeight();
                }
                callback();
                break;
            case MotionEvent.ACTION_UP:
                //小圓點(diǎn)恢復(fù)
                thumbScale = 4;
                break;
        }
        if (style == SLIDER) {
            invalidate();//“刷新”
        }
        return true;//這樣就不會(huì)繼續(xù)往下傳了
    }

    //監(jiān)聽(tīng)
    private void callback(){
        if(onSliderChangeListener != null){
//            onSliderChangeListener.progressChanged(progress * max);//和position/getWidth(橫)getHeight(豎)
                if (getWidth() > getHeight()) {
                    progress = position / getWidth();
                } else {
                    progress = position / getHeight();
                }
                onSliderChangeListener.progressChanged(progress * max);
        }
    }

    public int getStyle() {
        return style;
    }

    public void setStyle(int style) {
        this.style = style;
    }

    public float getProgress() {
        return progress;
    }

    public void setProgress(float progress) {
        this.progress = progress;
        if (progress < 1.0001) {
            //將進(jìn)度值轉(zhuǎn)換為控件中的尺寸位置
            if (getWidth() > getHeight()) {//橫
                position = progress * getWidth();
            } else position = progress * getHeight();
            invalidate();//
        }
    }

    public void setMax(int max) {
        this.max = max;
    }

    public void setOnSliderChangeListener(OnSliderChangeListener onSliderChangeListener) {
        this.onSliderChangeListener = onSliderChangeListener;
    }

    //實(shí)現(xiàn)回調(diào)數(shù)據(jù)給外部
    public interface OnSliderChangeListener{
        void progressChanged(float progress);
    }
}


MainActivity.java:

package com.example.a16palette;

import androidx.appcompat.app.AppCompatActivity;

import android.content.pm.ActivityInfo;
import android.os.Bundle;
import android.widget.SeekBar;

import java.util.Timer;
import java.util.TimerTask;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        final Slider slider = findViewById(R.id.slider);
        slider.setMax(50);
        slider.setStyle(Slider.SLIDER);//只設(shè)置這個(gè)時(shí)(無(wú)下面那)小圓點(diǎn)也會(huì)出來(lái)
//        //定時(shí)器 模擬進(jìn)度
//        new Timer().schedule(new TimerTask() {
//            @Override
//            public void run() {
//                 slider.setProgress((float)(slider.getProgress()+0.01));
//            }
//        },0,100);
        slider.setOnSliderChangeListener(new Slider.OnSliderChangeListener() {
            @Override
            public void progressChanged(float progress) {
                System.out.println(""+progress);
            }
        });

    }

    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);
    }

    @Override
    protected void onStart() {
        super.onStart();
    }

    @Override
    protected void onResume() {
        super.onResume();

        //設(shè)置橫豎屏
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR);
    }

    @Override
    protected void onPause() {
        super.onPause();
    }

    @Override
    protected void onStop() {
        super.onStop();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
    }
}

四、心得

學(xué)了這么久,唯一很明顯的變化就是現(xiàn)在打代碼的速度快了不少,但是要讓自己變思考邊自己寫(xiě)還是不太行,希望不久我的手速趕不上想的速度。


最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容