云炬Android开发笔记 15评价晒单功能实现(自定义评分控件和仿微信自动多图选择控件)
生活随笔
收集整理的這篇文章主要介紹了
云炬Android开发笔记 15评价晒单功能实现(自定义评分控件和仿微信自动多图选择控件)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
閱讀目錄
1. 曬單評價
1.1 點擊頁面跳轉的實現
1.2 自定義評價訂單的布局實現
1.3 星星布局的實現
2. 仿微信自動多圖及刪除控件
2.1 屬性值及控件的定義
2.2 圖片初始化方法onMearsure()方法
2.3 【設置避免重復測量的onMeasure()】
2.4??onLayout()方法的書寫
3. 對加號增加圖片事件的響應
3.1 增加圖片
?3.2 增加對圖片的刪除功能
?
?
?
- ?
回到頂部
1. 曬單評價
回到頂部
1.1 點擊頁面跳轉的實現
【說明】布局會使用自定義控件;
?
【點擊事件的處理】
?
【效果】
?
回到頂部
1.2 自定義評價訂單的布局實現
1 <?xml version="1.0" encoding="utf-8"?>2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"3 xmlns:app="http://schemas.android.com/apk/res-auto"4 android:layout_width="match_parent"5 android:layout_height="match_parent"6 android:orientation="vertical">7 8 <android.support.v7.widget.Toolbar9 android:id="@+id/tb_shop_cart" 10 android:layout_width="match_parent" 11 android:layout_height="75dp" 12 android:background="@android:color/holo_orange_dark" 13 android:gravity="center"> 14 15 <android.support.v7.widget.AppCompatTextView 16 android:layout_width="wrap_content" 17 android:layout_height="wrap_content" 18 android:layout_gravity="center" 19 android:text="評價曬單" 20 android:textColor="@android:color/white" 21 android:textSize="20sp" /> 22 23 <android.support.v7.widget.AppCompatTextView 24 android:id="@+id/top_tv_comment_commit" 25 android:layout_width="wrap_content" 26 android:layout_height="wrap_content" 27 android:layout_gravity="right" 28 android:layout_marginRight="20dp" 29 android:text="提交" 30 android:textColor="@android:color/white" 31 android:textSize="20sp" /> 32 </android.support.v7.widget.Toolbar> 33 34 <RelativeLayout 35 android:layout_width="match_parent" 36 android:layout_height="100dp"> 37 38 <android.support.v7.widget.AppCompatImageView 39 android:id="@+id/img_order_comment" 40 android:layout_width="80dp" 41 android:layout_height="80dp" 42 android:layout_centerVertical="true" 43 android:layout_marginLeft="10dp" /> 44 45 <TextView 46 android:id="@+id/tv_comment_title" 47 android:layout_width="wrap_content" 48 android:layout_height="wrap_content" 49 android:layout_marginLeft="20dp" 50 android:layout_marginTop="10dp" 51 android:layout_toRightOf="@id/img_order_comment" 52 android:text="評分" 53 android:textColor="#323232" /> 54 55 <com.flj.latte.ui.widget.StarLayout 56 android:id="@+id/custom_star_layout" 57 android:layout_width="match_parent" 58 android:layout_height="match_parent" 59 android:layout_below="@+id/tv_comment_title" 60 android:layout_toRightOf="@id/img_order_comment" /> 61 62 </RelativeLayout> 63 64 <android.support.v7.widget.AppCompatEditText 65 android:id="@+id/et_order_comment" 66 android:layout_width="match_parent" 67 android:layout_height="120dp" 68 android:background="@android:color/white" 69 android:gravity="top|left" 70 android:hint="寫下評論" 71 android:padding="10dp" /> 72 73 <com.flj.latte.ui.widget.AutoPhotoLayout 74 android:id="@+id/custom_auto_photo_layout" 75 android:layout_width="wrap_content" 76 android:layout_height="wrap_content" 77 app:icon_size="10sp" 78 app:item_margin="3" 79 app:line_count="5" 80 app:max_count="5" /> 81 82 </LinearLayout>?回到頂部
1.3 星星布局的實現
?
1 package com.flj.latte.ui.widget;2 3 import android.content.Context;4 import android.graphics.Color;5 import android.support.v7.widget.LinearLayoutCompat;6 import android.util.AttributeSet;7 import android.view.Gravity;8 import android.view.View;9 import android.view.ViewGroup;10 11 import com.flj.latte.ui.R;12 import com.joanzapata.iconify.widget.IconTextView;13 14 import java.util.ArrayList;15 16 17 public class StarLayout extends LinearLayoutCompat implements View.OnClickListener {18 19 private static final CharSequence ICON_UN_SELECT = "{fa-star-o}"; //空心圖標20 private static final CharSequence ICON_SELECTED = "{fa-star}"; //實心圖標21 private static final int STAR_TOTAL_COUNT = 5; //星星的數量22 private static final ArrayList<IconTextView> STARS = new ArrayList<>();23 24 public StarLayout(Context context) {25 this(context, null);26 }27 28 public StarLayout(Context context, AttributeSet attrs) {29 this(context, attrs, 0);30 }31 32 public StarLayout(Context context, AttributeSet attrs, int defStyleAttr) {33 super(context, attrs, defStyleAttr);34 initStarIcon();35 }36 //初始化星星37 private void initStarIcon() {38 for (int i = 0; i < STAR_TOTAL_COUNT; i++) {39 final IconTextView star = new IconTextView(getContext());40 star.setGravity(Gravity.CENTER);41 final LayoutParams lp =42 new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,43 ViewGroup.LayoutParams.MATCH_PARENT);44 lp.weight = 1;45 star.setLayoutParams(lp);46 star.setText(ICON_UN_SELECT);47 star.setTag(R.id.star_count, i);48 star.setTag(R.id.star_is_select, false); //默認沒有選中49 star.setOnClickListener(this);50 STARS.add(star); //創建的星星放到布局中;51 this.addView(star); //加到布局中;52 }53 }54 55 public int getStarCount() {56 int count = 0;57 for (int i = 0; i < STAR_TOTAL_COUNT; i++) {58 final IconTextView star = STARS.get(i);59 final boolean isSelect = (boolean) star.getTag(R.id.star_is_select);60 if (isSelect) {61 count++;62 }63 }64 return count;65 }66 67 private void selectStar(int count) {68 for (int i = 0; i <= count; i++) {69 if (i <= count) {70 final IconTextView star = STARS.get(i);71 star.setText(ICON_SELECTED);72 star.setTextColor(Color.RED);73 star.setTag(R.id.star_is_select, true);74 }75 }76 }77 78 private void unSelectStar(int count) {79 for (int i = 0; i < STAR_TOTAL_COUNT; i++) {80 if (i >= count) {81 final IconTextView star = STARS.get(i);82 star.setText(ICON_UN_SELECT);83 star.setTextColor(Color.GRAY);84 star.setTag(R.id.star_is_select, false);85 }86 }87 }88 89 @Override90 public void onClick(View v) {91 final IconTextView star = (IconTextView) v;92 //獲取第幾個星星93 final int count = (int) star.getTag(R.id.star_count);94 //獲取點擊狀態95 final boolean isSelect = (boolean) star.getTag(R.id.star_is_select);96 if (!isSelect) {97 selectStar(count);98 } else {99 unSelectStar(count); 100 } 101 } 102 }?
【效果】1-評價星星點擊選擇的效果.gif
?
回到頂部
2. 仿微信自動多圖及刪除控件
回到頂部
2.1 屬性值及控件的定義
【屬性值的定義】
【使用屬性值】
?
【為加號增加包邊】
?
【加號按鈕的設置和布局】
?
回到頂部
2.2 圖片初始化方法onMearsure()方法
1 package com.flj.latte.ui.widget;2 3 import android.content.Context;4 import android.content.res.TypedArray;5 import android.graphics.Color;6 import android.graphics.drawable.ColorDrawable;7 import android.net.Uri;8 import android.support.v7.app.AlertDialog;9 import android.support.v7.widget.AppCompatImageView;10 import android.support.v7.widget.LinearLayoutCompat;11 import android.util.AttributeSet;12 import android.view.Gravity;13 import android.view.View;14 import android.view.Window;15 import android.view.WindowManager;16 import android.view.animation.AlphaAnimation;17 18 import com.bumptech.glide.Glide;19 import com.bumptech.glide.load.engine.DiskCacheStrategy;20 import com.bumptech.glide.request.RequestOptions;21 import com.flj.latte.delegates.LatteDelegate;22 import com.flj.latte.ui.R;23 import com.joanzapata.iconify.widget.IconTextView;24 25 import java.util.ArrayList;26 27 public final class AutoPhotoLayout extends LinearLayoutCompat {28 29 private int mCurrentNum = 0; //首先判斷是第幾張圖片30 private final int mMaxNum; //最大容許多少張圖片;31 private final int mMaxLineNum; //一行圖片的數量;32 private IconTextView mIconAdd = null; //增加圖片的按鈕,是一張圖片;33 private LayoutParams mParams = null; //公共的一些屬性值;34 35 /**36 * 【效果】如果添加了圖片,要刪除圖片,則會彈出dialog,刪除之后“加號按鈕”會自動向前移動;37 */38 //要刪除的圖片ID39 private int mDeleteId = 0;40 private AppCompatImageView mTargetImageVew = null; //選中的圖片;41 private final int mImageMargin; //圖片的間距42 private LatteDelegate mDelegate = null; //對圖片的操作43 private ArrayList<View> mLineViews = null; //將每行增加的圖片存在arraylist中;44 private AlertDialog mTargetDialog = null; //刪除圖片的確認框;45 private static final String ICON_TEXT = "{fa-plus}"; //加號圖標;46 private final float mIconSize; //加號圖標的大小;47 //存儲所有的View;存儲方式是一行一行存儲的;如果有兩行就存儲兩行所有的View;48 private final ArrayList<ArrayList<View>> ALL_VIEWS = new ArrayList<>();49 private final ArrayList<Integer> LINE_HEIGHTS = new ArrayList<>(); //存儲每一個行的高度;50 51 52 53 //防止多次的測量和布局過程54 private boolean mIsOnceInitOnMeasure = false;55 private boolean mHasInitOnLayout = false;56 57 private static final RequestOptions OPTIONS = new RequestOptions()58 .centerCrop()59 .diskCacheStrategy(DiskCacheStrategy.NONE);60 61 public AutoPhotoLayout(Context context) {62 this(context, null);63 }64 65 public AutoPhotoLayout(Context context, AttributeSet attrs) {66 this(context, attrs, 0);67 }68 69 public AutoPhotoLayout(Context context, AttributeSet attrs, int defStyleAttr) {70 super(context, attrs, defStyleAttr);71 //從定義的attr.xml中將值取出;72 final TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.camera_flow_layout);73 mMaxNum = typedArray.getInt(R.styleable.camera_flow_layout_max_count, 1);74 mMaxLineNum = typedArray.getInt(R.styleable.camera_flow_layout_line_count, 3); //一行中什么都沒有傳遞,則默認值是3個“加號”75 mImageMargin = typedArray.getInt(R.styleable.camera_flow_layout_item_margin, 0); //無圖片上傳,則默認沒有間隙;76 mIconSize = typedArray.getDimension(R.styleable.camera_flow_layout_icon_size, 20); //無圖片,則默認是20的大小;77 typedArray.recycle(); //回收typedArray,防止內存泄露;78 }79 80 public final void setDelegate(LatteDelegate delegate) {81 this.mDelegate = delegate;82 }83 84 public final void onCropTarget(Uri uri) {85 createNewImageView();86 Glide.with(mDelegate)87 .load(uri)88 .apply(OPTIONS)89 .into(mTargetImageVew);90 }162 163 @Override 164 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 165 final int sizeWith = MeasureSpec.getSize(widthMeasureSpec); 166 final int modeWith = MeasureSpec.getMode(widthMeasureSpec); 167 final int sizeHeight = MeasureSpec.getSize(heightMeasureSpec); 168 final int modeHeight = MeasureSpec.getMode(heightMeasureSpec); 169 //wrap_content 170 int width = 0; 171 int height = 0; 172 //記錄每一行的寬度與高度 173 int lineWith = 0; 174 int lineHeight = 0; 175 //得到內部元素個數 176 int cCount = getChildCount(); 177 for (int i = 0; i < cCount; i++) { 178 final View child = getChildAt(i); 179 //測量子View的寬和高 180 measureChild(child, widthMeasureSpec, heightMeasureSpec); 181 //的搭配LayoutParams 182 final MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams(); 183 //子View占據的寬度 184 final int childWidth = child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin; 185 //子View占據的高度 186 final int childHeight = child.getMeasuredHeight() + lp.topMargin + lp.bottomMargin; 187 //開始換行 188 if (lineWith + childWidth > sizeWith - getPaddingLeft() - getPaddingRight()) { 189 //對比得到最大寬度 190 width = Math.max(width, lineWith); 191 //重置lineWidth 192 lineWith = childWidth; 193 height += lineHeight; 194 lineHeight = childHeight; 195 } else { 196 //未換行 197 //疊加行寬 198 lineWith += childWidth; 199 //得到當前最大的高度 200 lineHeight = Math.max(lineHeight, childHeight); 201 } 202 //最后一個子控件 203 if (i == cCount - 1) { 204 width = Math.max(lineWith, width); 205 //判斷是否超過最大拍照限制 206 height += lineHeight; 207 } 208 } 209 setMeasuredDimension( 210 modeWith == MeasureSpec.EXACTLY ? sizeWith : width + getPaddingLeft() + getPaddingRight(), 211 modeHeight == MeasureSpec.EXACTLY ? sizeHeight : height + getPaddingTop() + getPaddingBottom() 212 ); 213 //設置一行所有圖片的寬高 214 final int imageSideLen = sizeWith / mMaxLineNum; 215 //只初始化一次 216 if (!mIsOnceInitOnMeasure) { 217 mParams = new LayoutParams(imageSideLen, imageSideLen); 218 mIsOnceInitOnMeasure = true; 219 } 220 } 221回到頂部
2.3 【設置避免重復測量的onMeasure()】
?
【設置boolean值】
回到頂部
2.4? onLayout()方法的書寫
?【需要防止多次布局】
1 @Override2 protected void onLayout(boolean changed, int l, int t, int r, int b) {3 ALL_VIEWS.clear(); //清楚掉所有的之前的尺寸和參數;4 LINE_HEIGHTS.clear();5 // 當前ViewGroup的寬度 聲明需要使用的變量6 final int width = getWidth();7 int lineWidth = 0;8 int lineHeight = 0;9 if (!mHasInitOnLayout) { 10 mLineViews = new ArrayList<>(); 11 mHasInitOnLayout = true; 12 } 13 final int cCount = getChildCount(); 14 for (int i = 0; i < cCount; i++) { 15 final View child = getChildAt(i); 16 final MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams(); 17 final int childWith = child.getMeasuredWidth(); 18 final int childHeight = child.getMeasuredHeight(); 19 //如果需要換行 20 if (childWith + lineWidth + lp.leftMargin + lp.rightMargin > 21 width - getPaddingLeft() - getPaddingRight()) { 22 //記錄lineHeight 23 LINE_HEIGHTS.add(lineHeight); 24 //記錄當前一行的Views 25 ALL_VIEWS.add(mLineViews); 26 //重置寬和高 27 lineWidth = 0; 28 lineHeight = childHeight + lp.topMargin + lp.bottomMargin; 29 //重置View集合 30 mLineViews.clear(); 31 } 32 lineWidth += childWith + lp.leftMargin + lp.rightMargin; 33 lineHeight = Math.max(lineHeight, lineHeight + lp.topMargin + lp.bottomMargin); 34 mLineViews.add(child); 35 } 36 //處理最后一行 37 LINE_HEIGHTS.add(lineHeight); 38 ALL_VIEWS.add(mLineViews); 39 //設置子View位置 40 int left = getPaddingLeft(); 41 int top = getPaddingTop(); 42 //行數 43 final int lineNum = ALL_VIEWS.size(); 44 for (int i = 0; i < lineNum; i++) { 45 //當前行所有的View 46 mLineViews = ALL_VIEWS.get(i); 47 lineHeight = LINE_HEIGHTS.get(i); 48 final int size = mLineViews.size(); 49 for (int j = 0; j < size; j++) { 50 final View child = mLineViews.get(j); 51 //判斷child的狀態 52 if (child.getVisibility() == GONE) { 53 continue; 54 } 55 final MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams(); 56 //設置子View的邊距 57 final int lc = left + lp.leftMargin; 58 final int tc = top + lp.topMargin; 59 final int rc = lc + child.getMeasuredWidth() - mImageMargin; 60 final int bc = tc + child.getMeasuredHeight(); 61 //為子View進行布局 62 child.layout(lc, tc, rc, bc); 63 left += child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin; 64 } 65 left = getPaddingLeft(); 66 top += lineHeight; 67 } 68 mIconAdd.setLayoutParams(mParams); 69 mHasInitOnLayout = false; 70 }回到頂部
3. 對加號增加圖片事件的響應
回到頂部
3.1 增加圖片
【創建圖片和對圖片的剪裁】
?
?
【效果】可以增加兩種圖片,但是不能刪除;
回到頂部
?3.2 增加對圖片的刪除功能
?【刪除圖片的對話框的布局】
1 <?xml version="1.0" encoding="utf-8"?>2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"3 android:layout_width="match_parent"4 android:layout_height="wrap_content"5 android:layout_gravity="center"6 android:layout_marginLeft="10dp"7 android:layout_marginRight="10dp"8 android:background="@android:color/transparent"9 android:orientation="vertical" 10 android:paddingBottom="10dp"> 11 12 <Button 13 android:id="@+id/dialog_image_clicked_btn_delete" 14 android:layout_width="match_parent" 15 android:layout_height="50dp" 16 android:background="@drawable/btn_border_takephoto" 17 android:gravity="center" 18 android:text="刪除" 19 android:textColor="#323232" /> 20 21 <View 22 android:layout_width="match_parent" 23 android:layout_height="0.5dp" 24 android:layout_gravity="center" 25 android:background="@android:color/transparent" 26 android:gravity="center" /> 27 28 29 <Button 30 android:id="@+id/dialog_image_clicked_btn_undetermined" 31 android:layout_width="match_parent" 32 android:layout_height="50dp" 33 android:layout_gravity="center" 34 android:background="@drawable/btn_border_nativephoto" 35 android:text="待定" 36 android:textColor="#323232" /> 37 38 <View 39 android:layout_width="match_parent" 40 android:layout_height="10dp" 41 android:layout_gravity="center" 42 android:background="@android:color/transparent" 43 android:gravity="center" /> 44 45 <Button 46 android:id="@+id/dialog_image_clicked_btn_cancel" 47 android:layout_width="match_parent" 48 android:layout_height="50dp" 49 android:layout_gravity="center" 50 android:background="@drawable/btn_border" 51 android:text="取消" 52 android:textColor="#323232" /> 53 54 </LinearLayout>?
?
1 private void createNewImageView() {2 mTargetImageVew = new AppCompatImageView(getContext());3 mTargetImageVew.setId(mCurrentNum);4 mTargetImageVew.setLayoutParams(mParams);5 mTargetImageVew.setOnClickListener(new OnClickListener() {6 @Override7 public void onClick(View v) {8 //獲取要刪除的圖片ID9 mDeleteId = v.getId(); 10 mTargetDialog.show(); 11 final Window window = mTargetDialog.getWindow(); 12 if (window != null) { 13 window.setContentView(R.layout.dialog_image_click_panel); 14 window.setGravity(Gravity.BOTTOM); 15 window.setWindowAnimations(R.style.anim_panel_up_from_bottom); 16 window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); 17 final WindowManager.LayoutParams params = window.getAttributes(); 18 params.width = WindowManager.LayoutParams.MATCH_PARENT; 19 params.flags = WindowManager.LayoutParams.FLAG_DIM_BEHIND; 20 params.dimAmount = 0.5f; 21 window.setAttributes(params); 22 window.findViewById(R.id.dialog_image_clicked_btn_delete) //刪除按鈕的事件 23 .setOnClickListener(new OnClickListener() { 24 @Override 25 public void onClick(View v) { 26 //得到要刪除的圖片 27 final AppCompatImageView deleteImageViwe = 28 (AppCompatImageView) findViewById(mDeleteId); 29 //設置圖片逐漸消失的動畫 30 final AlphaAnimation animation = new AlphaAnimation(1, 0); 31 animation.setDuration(500); 32 animation.setRepeatCount(0); 33 animation.setFillAfter(true); 34 animation.setStartOffset(0); 35 deleteImageViwe.setAnimation(animation); 36 animation.start(); 37 AutoPhotoLayout.this.removeView(deleteImageViwe); 38 mCurrentNum -= 1; 39 //當數目達到上限時隱藏添加按鈕,不足時顯示 40 if (mCurrentNum < mMaxNum) { 41 mIconAdd.setVisibility(VISIBLE); 42 } 43 mTargetDialog.cancel(); 44 } 45 }); 46 window.findViewById(R.id.dialog_image_clicked_btn_undetermined) 47 .setOnClickListener(new OnClickListener() { 48 @Override 49 public void onClick(View v) { 50 mTargetDialog.cancel(); 51 } 52 }); 53 window.findViewById(R.id.dialog_image_clicked_btn_cancel) //取消按鈕的事件 54 .setOnClickListener(new OnClickListener() { 55 @Override 56 public void onClick(View v) { 57 mTargetDialog.cancel(); 58 } 59 }); 60 } 61 } 62 }); 63 //添加子View的時候傳入位置 64 this.addView(mTargetImageVew, mCurrentNum); 65 mCurrentNum++; 66 //當添加數目大于mMaxNum時,自動隱藏添加按鈕 67 if (mCurrentNum >= mMaxNum) { 68 mIconAdd.setVisibility(View.GONE); 69 } 70 }?
?
總結
以上是生活随笔為你收集整理的云炬Android开发笔记 15评价晒单功能实现(自定义评分控件和仿微信自动多图选择控件)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 程序员每天少吃 能活120岁
- 下一篇: 云炬Android开发笔记 16附加功