简体   繁体   中英

Android small counter next to a button

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:

在此输入图像描述

Question:

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?

Edit:

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...

在此输入图像描述

Code:

<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>

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);

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>

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 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM