在实现购物车的时候,当用户成功购买某一商品后,我们需要在代表购物车该控件上给出一个数量提示,提醒用户当前购买商品的数量。
例如
就我知道的实现该功能的方法有两种,第一种其实就是在购物车那个图标上面再画一个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>
用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 }
里面有多种构造方法,可以为多种控件实现数字提醒,大家可以研究研究
在这里我先讲讲我在项目中用到的方法,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 }
好了,基本上就是这样了。。。