在实现购物车的时候,当用户成功购买某一商品后,我们需要在代表购物车该控件上给出一个数量提示,提醒用户当前购买商品的数量。
例如
就我知道的实现该功能的方法有两种,第一种其实就是在购物车那个图标上面再画一个TextView上去,用一张9-path图片做背景图片,这种是最简单的实现该效果的方法。
另一种其实道理也差不多,用别人写好的类BadgeView一样可以实现,该类可以实现不同控件上的提醒,入RadioButton、Button、tabhost也可以用等等。
接下来我先将第一种方法
首先是一个Tabhost和一个RadioGroup布局
<TabHost xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/tabhost"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<FrameLayout
android:id="@android:id/tabcontent"
android:layout_width="fill_parent"
android:layout_height="fill_parent"/>
<TabWidget
android:id="@android:id/tabs"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:visibility="gone"/>
<RadioGroup
android:id="@+id/group"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:orientation="horizontal"
android:background="@color/black" >
<RadioButton
android:id="@+id/show_core"
android:drawableTop="@drawable/setbuttonbackground_main"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|center_horizontal"
android:layout_weight="1"
android:button="@null"
android:checked="true"
android:paddingTop="10dp"
android:gravity="center"/>
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:id="@+id/radioFram">
<RadioButton
android:drawableTop="@drawable/carta"
android:gravity="center"
android:id="@+id/show_student"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|center_horizontal"
android:button="@null"
android:paddingTop="10dp" />
<TextView
android:id="@+id/num"
android:background="@drawable/del3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:textColor="@color/white"
android:textStyle="bold"
android:gravity="center"
android:layout_marginBottom="20dp"/>
</FrameLayout>
<RadioButton
android:layout_weight="1"
android:drawableTop="@drawable/setbuttonbackground_cart"
android:gravity="center"
android:id="@+id/show_student_temp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|center_horizontal"
android:button="@null"
android:paddingTop="10dp"
android:visibility="gone"
/>
<RadioButton
android:drawableTop="@drawable/setbuttonbackground_account"
android:id="@+id/show_teacher"
android:layout_weight="1"
android:button="@null"
android:gravity="center"
android:paddingTop="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|center_horizontal"/>
<RadioButton
android:drawableTop="@drawable/setbuttonbackground_more"
android:id="@+id/show_more"
android:layout_weight="1"
android:button="@null"
android:gravity="center"
android:paddingTop="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|center_horizontal" />
</RadioGroup>
</RelativeLayout>
</TabHost>
View Code
用FrameLayout实现将红色的小圆点一层一层叠上去,就像我上面写的那样会出现一个问题,就是FrameLayout会覆盖RadioButton的点击事件,造成不能切换,解决办法是可以用一个隐藏的RadioButton代替,如上述代码所示,在Activity中只要将查询到的集合大小SetText进去就行了,这样便可实现。当然在Activity中需要重写Onresume()方法才能够即使更新提醒。
第二种方法,是BadgeView,在这里我给大家提供一个类,当然我也是网上找的,并且实现过,所以推荐给大家
1 package com.techrare.util;
2
3 import android.content.Context;
4 import android.content.res.Resources;
5 import android.graphics.Color;
6 import android.graphics.Typeface;
7 import android.graphics.drawable.ShapeDrawable;
8 import android.graphics.drawable.shapes.RoundRectShape;
9 import android.util.AttributeSet;
10 import android.util.TypedValue;
11 import android.view.Gravity;
12 import android.view.View;
13 import android.view.ViewGroup;
14 import android.view.ViewGroup.LayoutParams;
15 import android.view.ViewParent;
16 import android.view.animation.AccelerateInterpolator;
17 import android.view.animation.AlphaAnimation;
18 import android.view.animation.Animation;
19 import android.view.animation.DecelerateInterpolator;
20 import android.widget.FrameLayout;
21 import android.widget.RadioGroup;
22 import android.widget.TabWidget;
23 import android.widget.TextView;
24
25 /**
26 * A simple text label view that can be applied as a "badge" to any given {@link android.view.View}.
27 * This class is intended to be instantiated at runtime rather than included in XML layouts.
28 *
29 * @author Jeff Gilfelt
30 */
31 public class BadgeView extends TextView {
32
33 public static final int POSITION_TOP_LEFT = 1;
34 public static final int POSITION_TOP_RIGHT = 2;
35 public static final int POSITION_BOTTOM_LEFT = 3;
36 public static final int POSITION_BOTTOM_RIGHT = 4;
37
38 private static final int DEFAULT_MARGIN_DIP = 5;
39 private static final int DEFAULT_LR_PADDING_DIP = 5;
40 private static final int DEFAULT_CORNER_RADIUS_DIP = 8;
41 private static final int DEFAULT_POSITION = POSITION_TOP_RIGHT;
42 private static final int DEFAULT_BADGE_COLOR = Color.RED;
43 private static final int DEFAULT_TEXT_COLOR = Color.WHITE;
44
45 private static Animation fadeIn;
46 private static Animation fadeOut;
47
48 private Context context;
49 private View target;
50
51 private int badgePosition;
52 private int badgeMargin;
53 private int badgeColor;
54
55 private boolean isShown;
56
57 private ShapeDrawable badgeBg;
58
59 private int targetTabIndex;
60
61 public BadgeView(Context context) {
62 this(context, (AttributeSet) null, android.R.attr.textViewStyle);
63 }
64
65 public BadgeView(Context context, AttributeSet attrs) {
66 this(context, attrs, android.R.attr.textViewStyle);
67 }
68
69 /**
70 * Constructor -
71 *
72 * create a new BadgeView instance attached to a target {@link android.view.View}.
73 *
74 * @param context context for this view.
75 * @param target the View to attach the badge to.
76 */
77 public BadgeView(Context context, View target) {
78 this(context, null, android.R.attr.textViewStyle, target, 0);
79 }
80
81 /**
82 * Constructor -
83 *
84 * create a new BadgeView instance attached to a target {@link android.widget.TabWidget}
85 * tab at a given index.
86 *
87 * @param context context for this view.
88 * @param target the TabWidget to attach the badge to.
89 * @param index the position of the tab within the target.
90 */
91 public BadgeView(Context context, TabWidget target, int index) {
92 this(context, null, android.R.attr.textViewStyle, target, index);
93 }
94
95 public BadgeView(Context context, RadioGroup group, int index) {
96 this(context, null, android.R.attr.textViewStyle, group, index);
97 }
98
99
100
101
102 public BadgeView(Context context, AttributeSet attrs, int defStyle) {
103 this(context, attrs, defStyle, null, 0);
104 }
105
106 public BadgeView(Context context, AttributeSet attrs, int defStyle, View target, int tabIndex) {
107 super(context, attrs, defStyle);
108 init(context, target, tabIndex);
109 }
110
111 private void init(Context context, View target, int tabIndex) {
112
113 this.context = context;
114 this.target = target;
115 this.targetTabIndex = tabIndex;
116
117 // apply defaults
118 badgePosition = DEFAULT_POSITION;
119 badgeMargin = dipToPixels(DEFAULT_MARGIN_DIP);
120 badgeColor = DEFAULT_BADGE_COLOR;
121
122 setTypeface(Typeface.DEFAULT_BOLD);
123 int paddingPixels = dipToPixels(DEFAULT_LR_PADDING_DIP);
124 setPadding(paddingPixels, 0, paddingPixels, 0);
125 setTextColor(DEFAULT_TEXT_COLOR);
126
127 fadeIn = new AlphaAnimation(0, 1);
128 fadeIn.setInterpolator(new DecelerateInterpolator());
129 fadeIn.setDuration(200);
130
131 fadeOut = new AlphaAnimation(1, 0);
132 fadeOut.setInterpolator(new AccelerateInterpolator());
133 fadeOut.setDuration(200);
134
135 isShown = false;
136
137 if (this.target != null) {
138 applyTo(this.target);
139 } else {
140 show();
141 }
142
143 }
144
145 private void applyTo(View target) {
146
147 LayoutParams lp = target.getLayoutParams();
148 ViewParent parent = target.getParent();
149 FrameLayout container = new FrameLayout(context);
150
151 if (target instanceof TabWidget) {
152
153 // set target to the relevant tab child container
154 target = ((TabWidget) target).getChildTabViewAt(targetTabIndex);
155 this.target = target;
156
157 ((ViewGroup) target).addView(container,
158 new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
159
160 this.setVisibility(View.GONE);
161 container.addView(this);
162
163 } else {
164
165 // TODO verify that parent is indeed a ViewGroup
166 ViewGroup group = (ViewGroup) parent;
167 int index = group.indexOfChild(target);
168
169 group.removeView(target);
170 group.addView(container, index, lp);
171
172 container.addView(target);
173
174 this.setVisibility(View.GONE);
175 container.addView(this);
176
177 group.invalidate();
178
179 }
180
181 }
182
183 /**
184 * Make the badge visible in the UI.
185 *
186 */
187 public void show() {
188 show(false, null);
189 }
190
191 /**
192 * Make the badge visible in the UI.
193 *
194 * @param animate flag to apply the default fade-in animation.
195 */
196 public void show(boolean animate) {
197 show(animate, fadeIn);
198 }
199
200 /**
201 * Make the badge visible in the UI.
202 *
203 * @param anim Animation to apply to the view when made visible.
204 */
205 public void show(Animation anim) {
206 show(true, anim);
207 }
208
209 /**
210 * Make the badge non-visible in the UI.
211 *
212 */
213 public void hide() {
214 hide(false, null);
215 }
216
217 /**
218 * Make the badge non-visible in the UI.
219 *
220 * @param animate flag to apply the default fade-out animation.
221 */
222 public void hide(boolean animate) {
223 hide(animate, fadeOut);
224 }
225
226 /**
227 * Make the badge non-visible in the UI.
228 *
229 * @param anim Animation to apply to the view when made non-visible.
230 */
231 public void hide(Animation anim) {
232 hide(true, anim);
233 }
234
235 /**
236 * Toggle the badge visibility in the UI.
237 *
238 */
239 public void toggle() {
240 toggle(false, null, null);
241 }
242
243 /**
244 * Toggle the badge visibility in the UI.
245 *
246 * @param animate flag to apply the default fade-in/out animation.
247 */
248 public void toggle(boolean animate) {
249 toggle(animate, fadeIn, fadeOut);
250 }
251
252 /**
253 * Toggle the badge visibility in the UI.
254 *
255 * @param animIn Animation to apply to the view when made visible.
256 * @param animOut Animation to apply to the view when made non-visible.
257 */
258 public void toggle(Animation animIn, Animation animOut) {
259 toggle(true, animIn, animOut);
260 }
261
262 private void show(boolean animate, Animation anim) {
263 if (getBackground() == null) {
264 if (badgeBg == null) {
265 badgeBg = getDefaultBackground();
266 }
267 setBackgroundDrawable(badgeBg);
268 }
269 applyLayoutParams();
270
271 if (animate) {
272 this.startAnimation(anim);
273 }
274 this.setVisibility(View.VISIBLE);
275 isShown = true;
276 }
277
278 private void hide(boolean animate, Animation anim) {
279 this.setVisibility(View.GONE);
280 if (animate) {
281 this.startAnimation(anim);
282 }
283 isShown = false;
284 }
285
286 private void toggle(boolean animate, Animation animIn, Animation animOut) {
287 if (isShown) {
288 hide(animate && (animOut != null), animOut);
289 } else {
290 show(animate && (animIn != null), animIn);
291 }
292 }
293
294 /**
295 * Increment the numeric badge label. If the current badge label cannot be converted to
296 * an integer value, its label will be set to "0".
297 *
298 * @param offset the increment offset.
299 */
300 public int increment(int offset) {
301 CharSequence txt = getText();
302 int i;
303 if (txt != null) {
304 try {
305 i = Integer.parseInt(txt.toString());
306 } catch (NumberFormatException e) {
307 i = 0;
308 }
309 } else {
310 i = 0;
311 }
312 i = i + offset;
313 setText(String.valueOf(i));
314 return i;
315 }
316
317 /**
318 * Decrement the numeric badge label. If the current badge label cannot be converted to
319 * an integer value, its label will be set to "0".
320 *
321 * @param offset the decrement offset.
322 */
323 public int decrement(int offset) {
324 return increment(-offset);
325 }
326
327 private ShapeDrawable getDefaultBackground() {
328
329 int r = dipToPixels(DEFAULT_CORNER_RADIUS_DIP);
330 float[] outerR = new float[] {r, r, r, r, r, r, r, r};
331
332 RoundRectShape rr = new RoundRectShape(outerR, null, null);
333 ShapeDrawable drawable = new ShapeDrawable(rr);
334 drawable.getPaint().setColor(badgeColor);
335
336 return drawable;
337
338 }
339
340 private void applyLayoutParams() {
341
342 FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
343
344 switch (badgePosition) {
345 case POSITION_TOP_LEFT:
346 lp.gravity = Gravity.LEFT | Gravity.TOP;
347 lp.setMargins(badgeMargin, badgeMargin, 0, 0);
348 break;
349 case POSITION_TOP_RIGHT:
350 lp.gravity = Gravity.RIGHT | Gravity.TOP;
351 lp.setMargins(0, badgeMargin, badgeMargin, 0);
352 break;
353 case POSITION_BOTTOM_LEFT:
354 lp.gravity = Gravity.LEFT | Gravity.BOTTOM;
355 lp.setMargins(badgeMargin, 0, 0, badgeMargin);
356 break;
357 case POSITION_BOTTOM_RIGHT:
358 lp.gravity = Gravity.RIGHT | Gravity.BOTTOM;
359 lp.setMargins(0, 0, badgeMargin, badgeMargin);
360 break;
361 default:
362 break;
363 }
364
365 setLayoutParams(lp);
366
367 }
368
369 /**
370 * Returns the target View this badge has been attached to.
371 *
372 */
373 public View getTarget() {
374 return target;
375 }
376
377 /**
378 * Is this badge currently visible in the UI?
379 *
380 */
381 @Override
382 public boolean isShown() {
383 return isShown;
384 }
385
386 /**
387 * Returns the positioning of this badge.
388 *
389 * one of POSITION_TOP_LEFT, POSITION_TOP_RIGHT, POSITION_BOTTOM_LEFT, POSITION_BOTTOM_RIGHT.
390 *
391 */
392 public int getBadgePosition() {
393 return badgePosition;
394 }
395
396 /**
397 * Set the positioning of this badge.
398 *
399 * @param layoutPosition one of POSITION_TOP_LEFT, POSITION_TOP_RIGHT, POSITION_BOTTOM_LEFT, POSITION_BOTTOM_RIGHT.
400 *
401 */
402 public void setBadgePosition(int layoutPosition) {
403 this.badgePosition = layoutPosition;
404 }
405
406 /**
407 * Returns the horizontal/vertical margin from the target View that is applied to this badge.
408 *
409 */
410 public int getBadgeMargin() {
411 return badgeMargin;
412 }
413
414 /**
415 * Set the horizontal/vertical margin from the target View that is applied to this badge.
416 *
417 * @param badgeMargin the margin in pixels.
418 */
419 public void setBadgeMargin(int badgeMargin) {
420 this.badgeMargin = badgeMargin;
421 }
422
423 /**
424 * Returns the color value of the badge background.
425 *
426 */
427 public int getBadgeBackgroundColor() {
428 return badgeColor;
429 }
430
431 /**
432 * Set the color value of the badge background.
433 *
434 * @param badgeColor the badge background color.
435 */
436 public void setBadgeBackgroundColor(int badgeColor) {
437 this.badgeColor = badgeColor;
438 badgeBg = getDefaultBackground();
439 }
440
441 private int dipToPixels(int dip) {
442 Resources r = getResources();
443 float px = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dip, r.getDisplayMetrics());
444 return (int) px;
445 }
446
447 }
View Code
里面有多种构造方法,可以为多种控件实现数字提醒,大家可以研究研究
在这里我先讲讲我在项目中用到的方法,Activity中的使用
定义一个全局的BadgeView,在Activity中的OnCreate方法中找到TabWidget该控件,因为我的主界面是用TabHost布局的,在项目中用户购买后的商品是保存在sqlite里面,所以这里的查询到的大小就是购物车中的商品的数量了。
1 //數字提醒
2 public void getText(){
3 //查找本地数据库中的数据
4 List<ProductDetailToCart> list=new ArrayList<ProductDetailToCart>();
5 list=new ProductDao(MainActivity.this,"product").getProByCart();
6 int mycount=0;
7 for (int i = 0; i < list.size(); i++) {
8 ProductDetailToCart pro=list.get(i);
9 mycount+=pro.getPcount();
10 }
11
12 System.out.println("输出的数量是==="+mycount);
13
14 if(badge==null||!badge.isShown()){
15 badge = new BadgeView(MainActivity.this,tabs,1);//三个参数,1、this,2、当前控件(tab)3、在第几个控件上实现数字提醒
16 badge.setText(mycount+"");
17 badge.show();
18 }else{
19 badge.setText(mycount+"");
20 }
21 }
View Code
好了,基本上就是这样了。。。
经验的积累在于平时的点滴、