Skip to content
This repository was archived by the owner on Mar 27, 2022. It is now read-only.

Commit 2c327fc

Browse files
authored
Merge pull request #25 from sys1yagi/support_set_drawable_object
Support set drawable object
2 parents 143c264 + e0e4a77 commit 2c327fc

File tree

4 files changed

+217
-40
lines changed

4 files changed

+217
-40
lines changed

library/src/main/java/co/ceryle/segmentedbutton/SegmentedButton.java

Lines changed: 45 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -21,17 +21,22 @@
2121
import android.graphics.BitmapFactory;
2222
import android.graphics.Canvas;
2323
import android.graphics.Color;
24+
import android.graphics.ColorFilter;
2425
import android.graphics.Matrix;
2526
import android.graphics.Paint;
2627
import android.graphics.PorterDuff;
2728
import android.graphics.PorterDuffColorFilter;
2829
import android.graphics.Rect;
2930
import android.graphics.RectF;
3031
import android.graphics.Typeface;
32+
import android.graphics.drawable.BitmapDrawable;
33+
import android.graphics.drawable.Drawable;
34+
import android.support.v4.content.ContextCompat;
3135
import android.text.Layout;
3236
import android.text.StaticLayout;
3337
import android.text.TextPaint;
3438
import android.util.AttributeSet;
39+
import android.util.Log;
3540
import android.view.View;
3641

3742
public class SegmentedButton extends View {
@@ -56,8 +61,6 @@ public SegmentedButton(Context context, AttributeSet attrs, int defStyleAttr) {
5661
private float mClipAmount;
5762
private boolean clipLeftToRight;
5863

59-
private Paint mBitmapPaint;
60-
6164
private TextPaint mTextPaint;
6265
private StaticLayout mStaticLayout, mStaticLayoutOverlay;
6366
private Rect mTextBounds = new Rect();
@@ -123,42 +126,23 @@ else if (null != textTypeface) {
123126
}
124127

125128
private void initBitmap() {
126-
if (!hasDrawable)
127-
return;
128-
129-
mBitmap = BitmapFactory.decodeResource(context.getResources(), drawable);
130-
if (hasDrawableWidth || hasDrawableHeight)
131-
mBitmap = getResizedBitmap(mBitmap, drawableWidth, drawableHeight);
132-
133-
mBitmapPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
129+
if (hasDrawable) {
130+
mDrawable = ContextCompat.getDrawable(context, drawable);
131+
}
134132

135133
if (hasDrawableTint) {
136134
mBitmapNormalColor = new PorterDuffColorFilter(drawableTint, PorterDuff.Mode.SRC_IN);
137-
mBitmapPaint.setColorFilter(mBitmapNormalColor);
138135
}
139136

140137
if (hasDrawableTintOnSelection)
141138
mBitmapClipColor = new PorterDuffColorFilter(drawableTintOnSelection, PorterDuff.Mode.SRC_IN);
142139
}
143-
144-
public Bitmap getResizedBitmap(Bitmap bm, int newWidth, int newHeight) {
145-
int width = bm.getWidth();
146-
int height = bm.getHeight();
147-
148-
float scaleWidth = hasDrawableWidth ? ((float) newWidth) / width : 1;
149-
float scaleHeight = hasDrawableHeight ? ((float) newHeight) / height : 1;
150-
151-
Matrix matrix = new Matrix();
152-
matrix.postScale(scaleWidth, scaleHeight);
153-
154-
return Bitmap.createBitmap(bm, 0, 0, width, height, matrix, false);
155-
}
156-
140+
157141
private void measureTextWidth(int width) {
158142
if (!hasText)
159143
return;
160144

161-
int bitmapWidth = hasDrawable && drawableGravity.isHorizontal() ? mBitmap.getWidth() : 0;
145+
int bitmapWidth = hasDrawable && drawableGravity.isHorizontal() ? mDrawable.getIntrinsicWidth() : 0;
162146

163147
int textWidth = width - (bitmapWidth + getPaddingLeft() + getPaddingRight());
164148

@@ -177,11 +161,11 @@ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
177161
int heightRequirement = MeasureSpec.getSize(heightMeasureSpec);
178162

179163
int width = 0;
180-
int bitmapWidth = hasDrawable ? mBitmap.getWidth() : 0;
164+
int bitmapWidth = hasDrawable ? mDrawable.getIntrinsicWidth() : 0;
181165
int textWidth = hasText ? mStaticLayout.getWidth() : 0;
182166

183167
int height = getPaddingTop() + getPaddingBottom();
184-
int bitmapHeight = hasDrawable ? mBitmap.getHeight() : 0;
168+
int bitmapHeight = hasDrawable ? mDrawable.getIntrinsicHeight() : 0;
185169
int textHeight = hasText ? mStaticLayout.getHeight() : 0;
186170

187171
switch (widthMode) {
@@ -265,8 +249,8 @@ private void calculate(int width, int height) {
265249

266250
float bitmapHeight = 0, bitmapWidth = 0;
267251
if (hasDrawable) {
268-
bitmapHeight = mBitmap.getHeight();
269-
bitmapWidth = mBitmap.getWidth();
252+
bitmapHeight = mDrawable.getIntrinsicHeight();
253+
bitmapWidth = mDrawable.getIntrinsicWidth();
270254
}
271255

272256

@@ -336,7 +320,7 @@ private void calculate(int width, int height) {
336320

337321
private PorterDuffColorFilter mBitmapNormalColor, mBitmapClipColor;
338322

339-
private Bitmap mBitmap;
323+
private Drawable mDrawable;
340324

341325
@Override
342326
protected void onDraw(Canvas canvas) {
@@ -372,8 +356,7 @@ protected void onDraw(Canvas canvas) {
372356

373357
// Bitmap normal
374358
if (hasDrawable) {
375-
mBitmapPaint.setColorFilter(mBitmapNormalColor);
376-
canvas.drawBitmap(mBitmap, bitmap_X, bitmap_Y, mBitmapPaint);
359+
drawDrawableWithColorFilter(canvas, mBitmapNormalColor);
377360
}
378361
// NORMAL -end
379362

@@ -399,15 +382,29 @@ protected void onDraw(Canvas canvas) {
399382

400383
// Bitmap clip
401384
if (hasDrawable) {
402-
if (hasDrawableTintOnSelection)
403-
mBitmapPaint.setColorFilter(mBitmapClipColor);
404-
canvas.drawBitmap(mBitmap, bitmap_X, bitmap_Y, mBitmapPaint);
385+
drawDrawableWithColorFilter(canvas, mBitmapClipColor);
405386
}
406387
// CLIP -end
407388

408389
canvas.restore();
409390
}
410391

392+
private void drawDrawableWithColorFilter(Canvas canvas, ColorFilter colorFilter){
393+
int drawableX = (int)bitmap_X;
394+
int drawableY = (int)bitmap_Y;
395+
int drawableWidth = mDrawable.getIntrinsicWidth();
396+
if (hasDrawableWidth) {
397+
drawableWidth = this.drawableWidth;
398+
}
399+
int drawableHeight = mDrawable.getIntrinsicHeight();
400+
if (hasDrawableHeight) {
401+
drawableHeight = this.drawableHeight;
402+
}
403+
mDrawable.setColorFilter(colorFilter);
404+
mDrawable.setBounds(drawableX, drawableY, drawableX + drawableWidth, drawableY + drawableHeight);
405+
mDrawable.draw(canvas);
406+
}
407+
411408
public void clipToLeft(float clip) {
412409
clipLeftToRight = false;
413410
mClipAmount = 1.0f - clip;
@@ -557,8 +554,18 @@ public boolean isHorizontal() {
557554
* @param resId is your drawable's resource id
558555
*/
559556
public void setDrawable(int resId) {
560-
drawable = resId;
561-
mBitmap = BitmapFactory.decodeResource(context.getResources(), resId);
557+
setDrawable(ContextCompat.getDrawable(context, resId));
558+
}
559+
560+
/**
561+
* Sets button's drawable by given drawable object and its position
562+
*
563+
* @param drawable is your drawable object
564+
*/
565+
public void setDrawable(Drawable drawable){
566+
mDrawable = drawable;
567+
hasDrawable = true;
568+
requestLayout();
562569
}
563570

564571
/**

sample/src/main/java/co/ceryle/segmentedbutton/sample/MainActivity.java

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
package co.ceryle.segmentedbutton.sample;
22

3+
import android.graphics.Color;
34
import android.os.Handler;
45
import android.support.v7.app.AppCompatActivity;
56
import android.os.Bundle;
67
import android.view.View;
78
import android.widget.Button;
89

10+
import co.ceryle.segmentedbutton.SegmentedButton;
911
import co.ceryle.segmentedbutton.SegmentedButtonGroup;
12+
import co.ceryle.segmentedbutton.sample.drawable.BadgeDrawable;
1013

1114
public class MainActivity extends AppCompatActivity {
1215

@@ -51,9 +54,31 @@ public void run() {
5154
}
5255
};
5356
handler.postDelayed(runnable, 5000);
57+
58+
setupDynamicDrawables();
59+
}
60+
61+
private void setupDynamicDrawables() {
62+
final BadgeDrawable drawable = new BadgeDrawable(Color.RED, 80, 50, 3, 3);
63+
final SegmentedButton leftButton = (SegmentedButton) findViewById(R.id.left_button);
64+
leftButton.setDrawable(drawable);
65+
66+
SegmentedButtonGroup group = (SegmentedButtonGroup)findViewById(R.id.dynamic_drawable_group);
67+
group.setOnClickedButtonListener(new SegmentedButtonGroup.OnClickedButtonListener() {
68+
@Override
69+
public void onClickedButton(int position) {
70+
if(position == 0){
71+
drawable.setCount(drawable.getCount() + 1);
72+
leftButton.requestLayout();
73+
}
74+
}
75+
});
76+
77+
final SegmentedButton rightButton = (SegmentedButton) findViewById(R.id.right_button);
78+
rightButton.setDrawable(R.drawable.ic_b1);
5479
}
5580

5681
private void updateButton(int position) {
5782
button.setText("Position: " + position);
5883
}
59-
}
84+
}
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
package co.ceryle.segmentedbutton.sample.drawable;
2+
3+
import android.graphics.Canvas;
4+
import android.graphics.ColorFilter;
5+
import android.graphics.Paint;
6+
import android.graphics.Path;
7+
import android.graphics.PixelFormat;
8+
import android.graphics.Rect;
9+
import android.graphics.RectF;
10+
import android.graphics.drawable.Drawable;
11+
import android.support.annotation.NonNull;
12+
13+
public class BadgeDrawable extends Drawable {
14+
15+
private Paint paint;
16+
private int color;
17+
private int width;
18+
private int height;
19+
private int borderWidth;
20+
private int borderRadius;
21+
22+
private RectF rect;
23+
private Path path;
24+
private int count = 10;
25+
26+
public BadgeDrawable(int color, int width, int height, int borderWidth, int borderRadius) {
27+
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
28+
paint.setStyle(Paint.Style.FILL);
29+
paint.setTextSize(32);
30+
31+
path = new Path();
32+
path.setFillType(Path.FillType.EVEN_ODD);
33+
34+
rect = new RectF();
35+
36+
this.color = color;
37+
this.width = width;
38+
this.height = height;
39+
this.borderWidth = borderWidth;
40+
this.borderRadius = borderRadius;
41+
}
42+
43+
@Override
44+
public int getIntrinsicWidth() {
45+
return width;
46+
}
47+
48+
@Override
49+
public int getIntrinsicHeight() {
50+
return height;
51+
}
52+
53+
@Override
54+
protected void onBoundsChange(Rect bounds) {
55+
path.reset();
56+
57+
path.addRect(bounds.left, bounds.top, bounds.right, bounds.bottom, Path.Direction.CW);
58+
rect.set(bounds.left + borderWidth, bounds.top + borderWidth,
59+
bounds.right - borderWidth, bounds.bottom - borderWidth);
60+
path.addRoundRect(rect, borderRadius, borderRadius, Path.Direction.CW);
61+
}
62+
63+
@Override
64+
public void draw(@NonNull Canvas canvas) {
65+
paint.setColor(color);
66+
canvas.drawPath(path, paint);
67+
68+
Rect textBounds = new Rect();
69+
String countString = String.valueOf(count);
70+
paint.getTextBounds(countString, 0, countString.length(), textBounds);
71+
canvas.drawText(
72+
countString,
73+
rect.right - (rect.right - rect.left) / 2 - textBounds.width() / 2,
74+
rect.top + textBounds.height() / 2 + (rect.bottom - rect.top) / 2,
75+
paint
76+
);
77+
}
78+
79+
@Override
80+
public void setAlpha(int alpha) {
81+
paint.setAlpha(alpha);
82+
}
83+
84+
@Override
85+
public void setColorFilter(ColorFilter cf) {
86+
paint.setColorFilter(cf);
87+
}
88+
89+
@Override
90+
public int getOpacity() {
91+
return PixelFormat.TRANSLUCENT;
92+
}
93+
94+
public int getCount() {
95+
return count;
96+
}
97+
98+
public void setCount(int count) {
99+
this.count = count;
100+
}
101+
}

sample/src/main/res/layout/activity_main.xml

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -393,5 +393,49 @@
393393

394394
</co.ceryle.segmentedbutton.SegmentedButtonGroup>
395395

396+
<TextView
397+
android:layout_marginStart="10dp"
398+
android:layout_marginLeft="10dp"
399+
android:layout_marginTop="10dp"
400+
android:textSize="12sp"
401+
android:text="Using dynamic drawable:"
402+
android:layout_width="wrap_content"
403+
android:layout_height="wrap_content" />
396404

397-
</LinearLayout>
405+
<co.ceryle.segmentedbutton.SegmentedButtonGroup
406+
android:id="@+id/dynamic_drawable_group"
407+
android:layout_width="match_parent"
408+
android:layout_height="wrap_content"
409+
android:layout_margin="4dp"
410+
android:elevation="2dp"
411+
app:sbg_animateSelector="fastOutSlowIn"
412+
app:sbg_animateSelectorDuration="1000"
413+
app:sbg_backgroundColor="@color/black"
414+
app:sbg_position="0"
415+
app:sbg_radius="2dp"
416+
app:sbg_rippleColor="@color/white"
417+
app:sbg_selectorColor="@color/white">
418+
419+
<co.ceryle.segmentedbutton.SegmentedButton
420+
android:id="@+id/left_button"
421+
android:layout_width="0dp"
422+
android:layout_height="match_parent"
423+
android:layout_weight="1"
424+
app:sb_drawablePadding="8dp"
425+
app:sb_drawableGravity="right"
426+
app:sb_text="Left"
427+
app:sb_drawableTint="@color/white"
428+
app:sb_drawableTint_onSelection="@color/black"/>
429+
430+
<co.ceryle.segmentedbutton.SegmentedButton
431+
android:id="@+id/right_button"
432+
android:layout_width="0dp"
433+
android:layout_height="match_parent"
434+
android:layout_weight="1"
435+
app:sb_drawableGravity="right"
436+
app:sb_text="Right"
437+
app:sb_drawableTint="@color/white"
438+
app:sb_drawableTint_onSelection="@color/black"/>
439+
440+
</co.ceryle.segmentedbutton.SegmentedButtonGroup>
441+
</LinearLayout>

0 commit comments

Comments
 (0)