Reputation: 5027
I would like to add a small counter next to a button to show the remaining quantity for some items, for example, the remaining number of tips remaining unused. Targeted layout would be as shown:
I have researched the web and found that some say to use different pictures for each quantity. Yet how could it be solved if the quantity can be up to 100? Really necessary to draw such out?
I am thinking of to stick 2 buttons together in a RelativeLayout
such that when the user presses the bottom button, the top button will count up and down and setText
itself, but are there some better solutions or imports?
Thanks Rupesh for your codes and advice! I have implemented as follows. Yet do you know how to move the red circle textview further to the right? and the 20 cannot be properly shown in the red circle too...
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginTop="10dp" >
<Button
android:id="@+id/button_tip"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginBottom="1dp"
android:layout_marginLeft="2dp"
android:layout_marginRight="2dp"
android:layout_marginTop="5dp"
android:background="@drawable/orange_btn"
android:onClick="button_tip_click"
android:text="Hello" />
<TextView
android:layout_width="15dp"
android:layout_height="15dp"
android:layout_gravity="top|right"
android:background="@drawable/red_circle_btn"
android:gravity="center"
android:text="20"
android:textColor="@color/white"
android:textSize="8sp"
android:textStyle="bold" />
</FrameLayout>
Upvotes: 4
Views: 2145
Reputation: 24720
set Button's background Drawable to a custom Drawable like this one:
public class DecoratedTextViewDrawable extends LayerDrawable {
private int mCnt = 0;
private Paint mPaint;
private TextView mParent;
private ColorStateList mColors;
private Rect mBounds;
public DecoratedTextViewDrawable(TextView tv, Drawable[] layers, int cnt) {
super(layers);
mParent = tv;
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setTextAlign(Align.CENTER);
mPaint.setTextSize(tv.getTextSize());
mPaint.setTypeface(Typeface.DEFAULT_BOLD);
int[][] states = {
{android.R.attr.state_pressed}, {android.R.attr.state_focused}, {}
};
int[] colors = {
0xff0000aa, 0xff880000, 0xff00aa00
};
mColors = new ColorStateList(states, colors);
mBounds = new Rect();
setCnt(cnt);
}
public void setCnt(int cnt) {
mCnt = cnt;
String s = Integer.toString(cnt);
mPaint.getTextBounds(s, 0, s.length(), mBounds);
invalidateSelf();
}
@Override
protected boolean onStateChange(int[] state) {
invalidateSelf();
return super.onStateChange(state);
}
@Override
public boolean isStateful() {
return true;
}
@Override
public void draw(Canvas canvas) {
super.draw(canvas);
float x = mPaint.getTextSize() * 1.5f;
float r = mPaint.getTextSize() * 0.9f;
int base = mParent.getBaseline();
int[] stateSet = getState();
// Log.d(TAG, "draw " + StateSet.dump(stateSet));
int color = mColors.getColorForState(stateSet, 0xff000000);
mPaint.setColor(color);
canvas.drawCircle(x, base + mBounds.top + mBounds.height() / 2, r, mPaint);
mPaint.setColor(0xffeeeeee);
canvas.drawText(Integer.toString(mCnt), x, base, mPaint);
}
}
you can use it like this:
// Activity.onCreate method
LinearLayout ll = new LinearLayout(this);
ll.setOrientation(LinearLayout.VERTICAL);
int NUM = 5;
final int[] cnt = new int[NUM];
Random r = new Random();
for (int i = 0; i < NUM; i++) {
cnt[i] = r.nextInt(20);
Button b = new Button(this);
b.setText("Click me");
b.setTextSize(18);
b.setTag(i);
Drawable[] layers = {b.getBackground()};
Drawable d = new DecoratedTextViewDrawable(b, layers, cnt[i]);
b.setBackgroundDrawable(d);
OnClickListener l = new OnClickListener() {
@Override
public void onClick(View v) {
DecoratedTextViewDrawable d = (DecoratedTextViewDrawable) v.getBackground();
int idx = (Integer) v.getTag();
d.setCnt(++cnt[idx]);
}
};
b.setOnClickListener(l);
ll.addView(b);
}
setContentView(ll);
Upvotes: 4
Reputation: 129
use this - and keep updating the textviews text with the count
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/your_phone_call_image"
android:gravity="center"
android:scaletype="matrix"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="1"
android:padding="5dp"
android:gravity="top|right" <!--this is important-->
android:background="@drawable/your_counter_red_background"/>
</FrameLayout>
Upvotes: 2
Reputation: 1543
I suggest you can use a FrameLayout. 1.- you can use 2 images one for your button, one for the little circle and use a textview for the numbers... 2.- you can use one image for your button, and create a gradient for the little circle and a text view..
For the frameLayout see :http://developer.android.com/reference/android/widget/FrameLayout.html For the gradient see: How to make gradient background in android.
Upvotes: 0