diff --git a/library/src/main/java/ke/tang/ruler/RulerView.kt b/library/src/main/java/ke/tang/ruler/RulerView.kt index 08e2437..2210a0c 100644 --- a/library/src/main/java/ke/tang/ruler/RulerView.kt +++ b/library/src/main/java/ke/tang/ruler/RulerView.kt @@ -2,7 +2,11 @@ package ke.tang.ruler import android.content.Context import android.content.res.ColorStateList -import android.graphics.* +import android.graphics.Canvas +import android.graphics.Color +import android.graphics.Paint +import android.graphics.Rect +import android.graphics.RectF import android.graphics.drawable.Drawable import android.os.Parcel import android.os.Parcelable @@ -16,9 +20,7 @@ import androidx.annotation.ColorInt import androidx.annotation.DrawableRes import androidx.annotation.IntRange import androidx.core.math.MathUtils -import java.util.* -import kotlin.Comparator -import kotlin.collections.ArrayList +import java.util.Collections import kotlin.math.abs import kotlin.math.max import kotlin.math.min @@ -84,6 +86,7 @@ class RulerView @JvmOverloads constructor(context: Context, attrs: AttributeSet? requestLayout() invalidate() } + var notifyWhenMoving: Boolean = true @IntRange(from = 0, to = MAX_VALUE.toLong()) var maxValue: Int = 0 @@ -163,6 +166,7 @@ class RulerView @JvmOverloads constructor(context: Context, attrs: AttributeSet? init { setWillNotDraw(false) with(context.obtainStyledAttributes(attrs, R.styleable.RulerView, defStyleAttr, R.style.Widget_RulerView)) { + notifyWhenMoving = getBoolean(R.styleable.RulerView_notifyWhenMoving, true) stepWidth = getDimensionPixelOffset(R.styleable.RulerView_stepWidth, 10.toDip()) getString(R.styleable.RulerView_rulerValueFormatter).takeUnless { it.isNullOrBlank() }?.also { kotlin.runCatching { @@ -283,7 +287,35 @@ class RulerView @JvmOverloads constructor(context: Context, attrs: AttributeSet? if (labelRight > 0) { if (0 == index % sectionScaleCount || index == maxScaleCount || index == minScaleCount) { canvas.drawRect(left, rulerTop - scaleMaxHeight.toFloat(), right, rulerTop.toFloat(), rulerPaint) - canvas.drawText(label, centerX, fontY, labelPaint) + var labelX = centerX + var labelY = fontY + var diffIdx = index % sectionScaleCount + if (diffIdx != 0) { + when (index) { + minScaleCount -> { + labelPaint.textAlign = Paint.Align.CENTER + diffIdx = sectionScaleCount - diffIdx + if (labelPaint.measureText(label) > stepWidth * diffIdx) { + labelX -= labelPaint.measureText(label)/2 - scaleSize + labelY = rulerBottom - rulerSize - fontMetrics.bottom + } + } + + maxScaleCount -> { + labelPaint.textAlign = Paint.Align.CENTER + if (labelPaint.measureText(label) > stepWidth * diffIdx) { + labelX += labelPaint.measureText(label)/2 + scaleSize + labelY = rulerBottom - rulerSize - fontMetrics.bottom + } + } + + else -> labelPaint.textAlign = Paint.Align.CENTER + } + } + else { + labelPaint.textAlign = Paint.Align.CENTER + } + canvas.drawText(label, labelX, labelY, labelPaint) } else { canvas.drawRect(left, rulerTop - scaleMinHeight.toFloat(), right, rulerTop.toFloat(), rulerPaint) } @@ -302,7 +334,34 @@ class RulerView @JvmOverloads constructor(context: Context, attrs: AttributeSet? if (labelLeft < width) { if (0 == index % sectionScaleCount || index == maxScaleCount || index == minScaleCount) { canvas.drawRect(left, rulerBottom - rulerSize - scaleMaxHeight.toFloat(), right, rulerTop.toFloat(), rulerPaint) - canvas.drawText(label, centerX, fontY, labelPaint) + var labelX = centerX + var labelY = fontY + var diffIdx = index % sectionScaleCount + if (diffIdx != 0) { + when (index) { + minScaleCount -> { + labelPaint.textAlign = Paint.Align.CENTER + diffIdx = sectionScaleCount - diffIdx + if (labelPaint.measureText(label) > stepWidth * diffIdx) { + labelX -= labelPaint.measureText(label)/2 - scaleSize + labelY = rulerBottom - rulerSize - fontMetrics.bottom + } + } + + maxScaleCount -> { + labelPaint.textAlign = Paint.Align.CENTER + if (labelPaint.measureText(label) > stepWidth * diffIdx) { + labelX += labelPaint.measureText(label)/2 + scaleSize + labelY = rulerBottom - rulerSize - fontMetrics.bottom + } + } + else -> labelPaint.textAlign = Paint.Align.CENTER + } + } + else { + labelPaint.textAlign = Paint.Align.CENTER + } + canvas.drawText(label, labelX, labelY, labelPaint) } else { canvas.drawRect(left, rulerBottom - rulerSize - scaleMinHeight.toFloat(), right, rulerTop.toFloat(), rulerPaint) } @@ -359,6 +418,8 @@ class RulerView @JvmOverloads constructor(context: Context, attrs: AttributeSet? } override fun onTouchEvent(event: MotionEvent): Boolean { + if (!isEnabled) return false + event.pointerCount val x = event.x val y = event.y @@ -402,7 +463,8 @@ class RulerView @JvmOverloads constructor(context: Context, attrs: AttributeSet? if (it.toInt() in contentOffsetRange) dx else dx / 2 }.toInt() _value = getValueForContentOffset(contentOffset) - notifyValueChanged() + if (notifyWhenMoving) + notifyValueChanged() invalidate() } } @@ -452,6 +514,8 @@ class RulerView @JvmOverloads constructor(context: Context, attrs: AttributeSet? scrollToRoundedValue() } } + if (!notifyWhenMoving) + notifyValueChanged() } } invalidate() diff --git a/library/src/main/res/values/styleable.xml b/library/src/main/res/values/styleable.xml index 97d1743..c79b938 100644 --- a/library/src/main/res/values/styleable.xml +++ b/library/src/main/res/values/styleable.xml @@ -3,6 +3,7 @@ + diff --git a/sample/src/main/java/ke/tang/ruler/sample/MainActivity.kt b/sample/src/main/java/ke/tang/ruler/sample/MainActivity.kt index 338d723..9a864af 100644 --- a/sample/src/main/java/ke/tang/ruler/sample/MainActivity.kt +++ b/sample/src/main/java/ke/tang/ruler/sample/MainActivity.kt @@ -8,6 +8,8 @@ import android.util.TypedValue import android.view.View import android.widget.AdapterView import android.widget.ArrayAdapter +import android.widget.CompoundButton +import android.widget.RadioGroup import android.widget.SeekBar import android.widget.Toast import androidx.appcompat.app.AppCompatActivity @@ -48,6 +50,9 @@ class MainActivity : AppCompatActivity() { binding.ruler.textColor ) + binding.swEnable.setOnCheckedChangeListener { _, enabled -> binding.ruler.isEnabled = enabled } + binding.swNotifyWhenMoving.setOnCheckedChangeListener { _, enabled -> binding.ruler.notifyWhenMoving = enabled } + binding.stepWidth.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener { override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) { binding.ruler.stepWidth = (state.stepWidth + TypedValue.applyDimension( diff --git a/sample/src/main/res/layout/activity_main.xml b/sample/src/main/res/layout/activity_main.xml index af7d3f2..5a967a3 100644 --- a/sample/src/main/res/layout/activity_main.xml +++ b/sample/src/main/res/layout/activity_main.xml @@ -34,6 +34,20 @@ android:layout_height="wrap_content" android:orientation="vertical"> + + + + 标尺 + 启用 + 移动时通知 设置刻度间间距 设置刻度颜色 设置标尺颜色 diff --git a/sample/src/main/res/values/strings.xml b/sample/src/main/res/values/strings.xml index ed3f587..136e311 100644 --- a/sample/src/main/res/values/strings.xml +++ b/sample/src/main/res/values/strings.xml @@ -1,5 +1,7 @@ Ruler + Enable + Notify when moving Set the distance between scales Set scale color Set the ruler color diff --git a/version.gradle b/version.gradle index 0428ed6..8d8dca9 100644 --- a/version.gradle +++ b/version.gradle @@ -4,7 +4,7 @@ ext { minSdkVersion : 15, targetSdkVersion : 28, versionCode : 6, - versionName : '1.0.5', + versionName : '1.0.7', kotlin : '1.9.22', build : '8.2.2', library : [