一、目的
寫(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ě)還是不太行,希望不久我的手速趕不上想的速度。
