|
3 | 3 | import android.content.Context; |
4 | 4 | import android.graphics.Bitmap; |
5 | 5 | import android.graphics.BitmapFactory; |
| 6 | +import android.graphics.Canvas; |
| 7 | +import android.graphics.Paint; |
| 8 | +import android.graphics.PorterDuff; |
6 | 9 | import android.graphics.drawable.BitmapDrawable; |
7 | 10 | import android.os.Build; |
8 | 11 | import android.util.Log; |
@@ -74,6 +77,15 @@ public class ReactSlider extends AppCompatSeekBar { |
74 | 77 | /** Upper limit based on the SeekBar progress 0..total steps */ |
75 | 78 | private int mUpperLimit; |
76 | 79 |
|
| 80 | + /** Thumb size in pixels (0 = default) */ |
| 81 | + private int mThumbSizePx = 0; |
| 82 | + |
| 83 | + /** Original thumb drawable URI */ |
| 84 | + @Nullable private String mThumbImageUri = null; |
| 85 | + |
| 86 | + /** Cached thumb tint color */ |
| 87 | + @Nullable private Integer mThumbTintColor = null; |
| 88 | + |
77 | 89 | public ReactSlider(Context context, @Nullable AttributeSet attrs) { |
78 | 90 | super(context, attrs); |
79 | 91 | I18nUtil sharedI18nUtilInstance = I18nUtil.getInstance(); |
@@ -299,15 +311,88 @@ public BitmapDrawable call() { |
299 | 311 | return bitmapDrawable; |
300 | 312 | } |
301 | 313 |
|
302 | | - public void setThumbImage(final String uri) { |
303 | | - if (uri != null) { |
304 | | - setThumb(getBitmapDrawable(uri)); |
305 | | - // Enable alpha channel for the thumbImage |
| 314 | + public void setThumbImage(@Nullable final String uri) { |
| 315 | + mThumbImageUri = uri; |
| 316 | + updateThumbImage(); |
| 317 | + } |
| 318 | + |
| 319 | + public void setThumbSize(final double size) { |
| 320 | + float density = getResources().getDisplayMetrics().density; |
| 321 | + mThumbSizePx = size > 0 ? Math.round((float) size * density) : 0; |
| 322 | + updateThumbImage(); |
| 323 | + } |
| 324 | + |
| 325 | + public void setThumbTintColor(@Nullable final Integer color) { |
| 326 | + mThumbTintColor = color; |
| 327 | + if (mThumbImageUri != null || mThumbSizePx > 0) { |
| 328 | + updateThumbImage(); |
| 329 | + } else { |
| 330 | + applyThumbTintColorFilter(); |
| 331 | + } |
| 332 | + } |
| 333 | + |
| 334 | + private void applyThumbTintColorFilter() { |
| 335 | + if (getThumb() == null) { |
| 336 | + return; |
| 337 | + } |
| 338 | + |
| 339 | + if (mThumbTintColor != null) { |
| 340 | + getThumb().setColorFilter(mThumbTintColor, PorterDuff.Mode.SRC_IN); |
| 341 | + } else { |
| 342 | + getThumb().clearColorFilter(); |
| 343 | + } |
| 344 | + } |
| 345 | + |
| 346 | + private void updateThumbImage() { |
| 347 | + if (mThumbImageUri != null) { |
| 348 | + BitmapDrawable drawable = getBitmapDrawable(mThumbImageUri); |
| 349 | + if (drawable != null) { |
| 350 | + if (mThumbSizePx > 0) { |
| 351 | + Bitmap originalBitmap = drawable.getBitmap(); |
| 352 | + Bitmap scaledBitmap = |
| 353 | + Bitmap.createScaledBitmap(originalBitmap, mThumbSizePx, mThumbSizePx, true); |
| 354 | + setThumb(new BitmapDrawable(getResources(), scaledBitmap)); |
| 355 | + } else { |
| 356 | + setThumb(drawable); |
| 357 | + } |
| 358 | + applyThumbTintColorFilter(); |
| 359 | + // Enable alpha channel for the thumbImage |
| 360 | + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { |
| 361 | + setSplitTrack(false); |
| 362 | + } |
| 363 | + return; |
| 364 | + } |
| 365 | + } |
| 366 | + |
| 367 | + if (mThumbSizePx > 0) { |
| 368 | + Bitmap bitmap = Bitmap.createBitmap(mThumbSizePx, mThumbSizePx, Bitmap.Config.ARGB_8888); |
| 369 | + Canvas canvas = new Canvas(bitmap); |
| 370 | + |
| 371 | + int fillColor = |
| 372 | + mThumbTintColor != null |
| 373 | + ? mThumbTintColor |
| 374 | + : (getThumbTintList() != null ? getThumbTintList().getDefaultColor() : 0xFFFFFFFF); |
| 375 | + |
| 376 | + Paint fillPaint = new Paint(Paint.ANTI_ALIAS_FLAG); |
| 377 | + fillPaint.setStyle(Paint.Style.FILL); |
| 378 | + fillPaint.setColor(fillColor); |
| 379 | + float radius = mThumbSizePx / 2f; |
| 380 | + canvas.drawCircle(radius, radius, radius, fillPaint); |
| 381 | + |
| 382 | + Paint strokePaint = new Paint(Paint.ANTI_ALIAS_FLAG); |
| 383 | + strokePaint.setStyle(Paint.Style.STROKE); |
| 384 | + strokePaint.setStrokeWidth(1); |
| 385 | + strokePaint.setColor(0x1A000000); |
| 386 | + canvas.drawCircle(radius, radius, radius - 0.5f, strokePaint); |
| 387 | + |
| 388 | + setThumb(new BitmapDrawable(getResources(), bitmap)); |
| 389 | + applyThumbTintColorFilter(); |
306 | 390 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { |
307 | 391 | setSplitTrack(false); |
308 | 392 | } |
309 | 393 | } else { |
310 | | - setThumb(getThumb()); |
| 394 | + // No special sizing; keep existing thumb, only apply tint if needed. |
| 395 | + applyThumbTintColorFilter(); |
311 | 396 | } |
312 | 397 | } |
313 | 398 | } |
0 commit comments