写这个小Demo,也是因为刚好手里没什么事然后看到很多朋友还在好奇这个阻尼界面效果,还有自定义标签,其实这个标签因为现在Google已经有推出更好使用的东西可以替代,那就是“FlexboxLayout”,关于“FlexboxLayout”我之前的文章也介绍过。不清楚的可以回过去看下。关于titleBar的显示和隐藏,其实就是当我们在触摸滑动的时候,监听就可以了。这里贴出来,就是希望和大家共同学习,OK,先看效果吧。
布局文件activity_main:
1 <?xml version="1.0" encoding="utf-8"?> 2 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent"> 5 6 <com.example.administrator.sbdemo.MyScrollView 7 android:id="@+id/scrollView" 8 android:layout_width="match_parent" 9 android:layout_height="match_parent"> 10 11 <RelativeLayout 12 android:layout_width="match_parent" 13 android:layout_height="match_parent"> 14 15 <ImageView 16 android:id="@+id/img" 17 android:layout_width="match_parent" 18 android:layout_height="200dp" 19 android:layout_gravity="center" 20 android:scaleType="centerCrop" 21 android:src="@mipmap/fj" /> 22 23 <TextView 24 android:id="@+id/companyName" 25 android:layout_width="wrap_content" 26 android:layout_height="wrap_content" 27 android:layout_below="@+id/img" 28 android:layout_centerInParent="true" 29 android:layout_marginTop="10dp" 30 android:text="@string/company" 31 android:textColor="@android:color/black" 32 android:textSize="18sp" 33 android:textStyle="bold" /> 34 35 <LinearLayout 36 android:id="@+id/informationLayout" 37 android:layout_width="wrap_content" 38 android:layout_height="wrap_content" 39 android:layout_below="@+id/companyName" 40 android:layout_centerInParent="true" 41 android:layout_marginTop="8dp" 42 android:orientation="horizontal"> 43 44 <TextView 45 android:layout_width="wrap_content" 46 android:layout_height="wrap_content" 47 android:text="@string/companyNumber" /> 48 49 <TextView 50 android:layout_width="wrap_content" 51 android:layout_height="wrap_content" 52 android:layout_marginLeft="5dp" 53 android:drawableLeft="@mipmap/pos" 54 android:drawablePadding="3dp" 55 android:paddingBottom="7dp" 56 android:paddingTop="7dp" 57 android:text="@string/address" /> 58 </LinearLayout> 59 60 <LinearLayout 61 android:id="@+id/senLayout" 62 android:layout_width="wrap_content" 63 android:layout_height="wrap_content" 64 android:layout_below="@+id/informationLayout" 65 android:layout_centerInParent="true" 66 android:orientation="horizontal"> 67 68 <TextView 69 android:id="@+id/senP" 70 style="@style/tv_style" 71 android:layout_marginRight="8dp" 72 android:text="@string/senProject" 73 android:textColor="@android:color/white" /> 74 75 <TextView 76 style="@style/tv_style" 77 android:layout_marginLeft="8dp" 78 android:text="@string/senInformation" 79 android:textColor="@android:color/white" /> 80 </LinearLayout> 81 82 <View 83 android:id="@+id/line" 84 android:layout_width="match_parent" 85 android:layout_height="1dp" 86 android:layout_below="@+id/senLayout" 87 android:layout_marginTop="30dp" 88 android:background="@android:color/darker_gray" /> 89 90 <TextView 91 android:id="@+id/he" 92 android:layout_width="wrap_content" 93 android:layout_height="wrap_content" 94 android:layout_below="@+id/line" 95 android:layout_marginLeft="10dp" 96 android:layout_marginTop="12dp" 97 android:text="@string/heProject" 98 android:textColor="@android:color/black" 99 android:textSize="17sp" 100 android:textStyle="bold" /> 101 102 <LinearLayout 103 android:id="@+id/evaluateLayout" 104 105 android:layout_width="wrap_content" 106 android:layout_height="wrap_content" 107 android:layout_below="@+id/he" 108 android:layout_marginLeft="10dp" 109 android:orientation="horizontal"> 110 111 <TextView 112 android:layout_width="wrap_content" 113 android:layout_height="wrap_content" 114 android:layout_gravity="center" 115 android:layout_marginBottom="10dp" 116 android:layout_marginTop="10dp" 117 android:text="@string/evaluate" 118 android:textColor="@android:color/black" 119 android:textSize="17sp" /> 120 121 <RatingBar 122 style="?android:attr/ratingBarStyleSmall" 123 android:layout_width="wrap_content" 124 android:layout_height="wrap_content" 125 android:layout_gravity="center" 126 android:layout_marginLeft="30dp" 127 android:isIndicator="false" /> 128 </LinearLayout> 129 130 <com.example.administrator.sbdemo.FLayout 131 android:id="@+id/fl" 132 android:layout_width="match_parent" 133 android:layout_height="wrap_content" 134 android:layout_below="@+id/evaluateLayout" 135 android:layout_marginTop="8dp"></com.example.administrator.sbdemo.FLayout> 136 137 <View 138 android:id="@+id/line2" 139 android:layout_width="match_parent" 140 android:layout_height="1dp" 141 android:layout_below="@+id/fl" 142 android:layout_marginTop="30dp" 143 android:background="@android:color/darker_gray" /> 144 145 <com.example.administrator.sbdemo.MyListview 146 android:id="@+id/lv" 147 android:layout_width="match_parent" 148 android:layout_height="wrap_content" 149 android:layout_below="@+id/line2" 150 android:layout_marginTop="15dp"> 151 152 </com.example.administrator.sbdemo.MyListview> 153 </RelativeLayout> 154 155 156 </com.example.administrator.sbdemo.MyScrollView> 157 158 <include layout="@layout/title_layout" /> 159 160 </RelativeLayout>
布局item:
1 <?xml version="1.0" encoding="utf-8"?> 2 <RelativeLayout 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 7 <com.example.administrator.sbdemo.Circle_ImageView 8 android:id="@+id/id_icon" 9 android:layout_width="50dp" 10 android:layout_height="50dp" 11 android:layout_marginLeft="10dp" 12 android:layout_marginTop="15dp" 13 android:scaleType="centerCrop" 14 android:src="@mipmap/log" 15 app:civ_border_color="@android:color/black" 16 app:civ_border_width="2dp" /> 17 18 <TextView 19 android:id="@+id/name" 20 android:layout_width="wrap_content" 21 android:layout_height="wrap_content" 22 android:layout_marginLeft="10dp" 23 android:layout_marginTop="10dp" 24 android:layout_toRightOf="@+id/id_icon" 25 android:text="火龙裸先生" 26 android:textColor="@android:color/black" 27 android:textSize="17sp" /> 28 29 30 <TextView 31 android:id="@+id/Code" 32 android:layout_width="wrap_content" 33 android:layout_height="wrap_content" 34 android:layout_below="@+id/name" 35 android:layout_marginLeft="10dp" 36 android:layout_marginTop="5dp" 37 android:layout_toRightOf="@+id/id_icon" 38 android:text="ABCDEFG" 39 android:textSize="17sp" /> 40 41 <RatingBar 42 style="?android:attr/ratingBarStyleSmall" 43 android:layout_width="wrap_content" 44 android:layout_height="40dp" 45 android:layout_alignBaseline="@+id/name" 46 android:layout_alignParentRight="true" 47 android:layout_gravity="center" 48 android:layout_marginLeft="30dp" 49 android:layout_marginRight="10dp" 50 android:isIndicator="false" 51 android:paddingBottom="10dp" 52 android:paddingTop="10dp" /> 53 54 <TextView 55 android:id="@+id/message" 56 android:layout_width="wrap_content" 57 android:layout_height="wrap_content" 58 android:layout_below="@+id/id_icon" 59 android:layout_marginLeft="10dp" 60 android:layout_marginTop="10dp" 61 android:text="啊啊啊啊啊 坑爹啊" 62 android:textColor="@android:color/black" 63 android:textSize="15sp" 64 android:textStyle="bold" /> 65 66 <TextView 67 android:id="@+id/time" 68 android:layout_width="wrap_content" 69 android:layout_height="wrap_content" 70 android:layout_below="@+id/message" 71 android:layout_marginLeft="10dp" 72 android:layout_marginTop="10dp" 73 android:text="2020-8-9" /> 74 75 <TextView 76 android:id="@+id/money" 77 android:layout_width="wrap_content" 78 android:layout_height="wrap_content" 79 android:layout_below="@+id/message" 80 android:layout_marginLeft="10dp" 81 android:layout_marginTop="10dp" 82 android:layout_toRightOf="@+id/time" 83 android:text="交易金额¥555" /> 84 </RelativeLayout>
布局title_layout:
1 <?xml version="1.0" encoding="utf-8"?> 2 3 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 4 android:id="@+id/titleBar" 5 android:layout_width="match_parent" 6 android:layout_height="48dp"> 7 8 <ImageView 9 android:id="@+id/backImage" 10 android:layout_width="30dp" 11 android:layout_height="30dp" 12 android:layout_centerVertical="true" 13 android:scaleType="centerCrop" 14 android:src="@mipmap/balk" /> 15 16 <TextView 17 android:id="@+id/textview" 18 android:layout_width="wrap_content" 19 android:layout_height="match_parent" 20 android:layout_marginLeft="1dp" 21 android:layout_toRightOf="@+id/backImage" 22 android:background="#00000000" 23 android:gravity="center" 24 android:text="@string/back" 25 android:textColor="@android:color/white" 26 android:textSize="18sp" /> 27 28 <TextView 29 30 android:layout_width="wrap_content" 31 android:layout_height="match_parent" 32 android:layout_alignParentRight="true" 33 android:layout_marginLeft="1dp" 34 android:layout_marginRight="15dp" 35 android:background="#00000000" 36 android:gravity="center" 37 android:paddingLeft="10dp" 38 android:paddingRight="10dp" 39 android:text="更多" 40 android:textColor="@android:color/white" 41 android:textSize="18sp" /> 42 </RelativeLayout>
实体类Model.java:
1 package com.example.administrator.sbdemo; 2 3 /** 4 * 参数:Created by Administrator on 2017/3/13. 5 * 类作用:Created by Administrator on 2017/3/13. 6 */ 7 public class Model { 8 String name; 9 String money; 10 String code; 11 String time; 12 String message; 13 14 public String getMoney() { 15 return money; 16 } 17 18 public void setMoney(String money) { 19 this.money = money; 20 } 21 22 public String getName() { 23 return name; 24 } 25 26 public void setName(String name) { 27 this.name = name; 28 } 29 30 public String getCode() { 31 return code; 32 } 33 34 public void setCode(String code) { 35 this.code = code; 36 } 37 38 public String getTime() { 39 return time; 40 } 41 42 public void setTime(String time) { 43 this.time = time; 44 } 45 46 public String getMessage() { 47 return message; 48 } 49 50 public void setMessage(String message) { 51 this.message = message; 52 } 53 }
自定义标签类Flayout.java:
1 package com.example.administrator.sbdemo; 2 3 import android.content.Context; 4 import android.util.AttributeSet; 5 import android.view.View; 6 import android.view.ViewGroup; 7 8 import java.util.ArrayList; 9 import java.util.List; 10 11 /** 12 * Created by taofangxin on 16/4/16. 13 */ 14 public class FLayout extends ViewGroup { 15 16 private Context mContext; 17 private int usefulWidth; // the space of a line we can use(line's width minus the sum of left and right padding 18 private int lineSpacing = 0; // the spacing between lines in FLayout 19 List<View> childList = new ArrayList(); 20 List<Integer> lineNumList = new ArrayList(); 21 22 public FLayout(Context context) { 23 this(context, null); 24 } 25 26 public FLayout(Context context, AttributeSet attrs) { 27 this(context, attrs, 0); 28 } 29 30 public FLayout(Context context, AttributeSet attrs, int defStyleAttr) { 31 super(context, attrs, defStyleAttr); 32 mContext = context; 33 /* TypedArray mTypedArray = context.obtainStyledAttributes(attrs, 34 R.styleable.FLayout); 35 lineSpacing = mTypedArray.getDimensionPixelSize( 36 R.styleable.FLayout_lineSpacing, 0);*/ 37 //mTypedArray.recycle(); 38 } 39 40 @Override 41 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 42 int mPaddingLeft = getPaddingLeft(); 43 int mPaddingRight = getPaddingRight(); 44 int mPaddingTop = getPaddingTop(); 45 int mPaddingBottom = getPaddingBottom(); 46 47 int widthSize = MeasureSpec.getSize(widthMeasureSpec); 48 int heightMode = MeasureSpec.getMode(heightMeasureSpec); 49 int heightSize = MeasureSpec.getSize(heightMeasureSpec); 50 int lineUsed = mPaddingLeft + mPaddingRight; 51 int lineY = mPaddingTop; 52 int lineHeight = 0; 53 for (int i = 0; i < this.getChildCount(); i++) { 54 View child = this.getChildAt(i); 55 if (child.getVisibility() == GONE) { 56 continue; 57 } 58 int spaceWidth = 0; 59 int spaceHeight = 0; 60 LayoutParams childLp = child.getLayoutParams(); 61 if (childLp instanceof MarginLayoutParams) { 62 measureChildWithMargins(child, widthMeasureSpec, 0, heightMeasureSpec, lineY); 63 MarginLayoutParams mlp = (MarginLayoutParams) childLp; 64 spaceWidth = mlp.leftMargin + mlp.rightMargin; 65 spaceHeight = mlp.topMargin + mlp.bottomMargin; 66 } else { 67 measureChild(child, widthMeasureSpec, heightMeasureSpec); 68 } 69 70 int childWidth = child.getMeasuredWidth(); 71 int childHeight = child.getMeasuredHeight(); 72 spaceWidth += childWidth; 73 spaceHeight += childHeight; 74 75 if (lineUsed + spaceWidth > widthSize) { 76 //approach the limit of width and move to next line 77 lineY += lineHeight + lineSpacing; 78 lineUsed = mPaddingLeft + mPaddingRight; 79 lineHeight = 0; 80 } 81 if (spaceHeight > lineHeight) { 82 lineHeight = spaceHeight; 83 } 84 lineUsed += spaceWidth; 85 } 86 setMeasuredDimension( 87 widthSize, 88 heightMode == MeasureSpec.EXACTLY ? heightSize : lineY + lineHeight + mPaddingBottom 89 ); 90 } 91 92 @Override 93 protected void onLayout(boolean changed, int l, int t, int r, int b) { 94 int mPaddingLeft = getPaddingLeft(); 95 int mPaddingRight = getPaddingRight(); 96 int mPaddingTop = getPaddingTop(); 97 98 int lineX = mPaddingLeft; 99 int lineY = mPaddingTop; 100 int lineWidth = r - l; 101 usefulWidth = lineWidth - mPaddingLeft - mPaddingRight; 102 int lineUsed = mPaddingLeft + mPaddingRight; 103 int lineHeight = 0; 104 int lineNum = 0; 105 106 lineNumList.clear(); 107 for (int i = 0; i < this.getChildCount(); i++) { 108 View child = this.getChildAt(i); 109 if (child.getVisibility() == GONE) { 110 continue; 111 } 112 int spaceWidth = 0; 113 int spaceHeight = 0; 114 int left = 0; 115 int top = 0; 116 int right = 0; 117 int bottom = 0; 118 int childWidth = child.getMeasuredWidth(); 119 int childHeight = child.getMeasuredHeight(); 120 121 LayoutParams childLp = child.getLayoutParams(); 122 if (childLp instanceof MarginLayoutParams) { 123 MarginLayoutParams mlp = (MarginLayoutParams) childLp; 124 spaceWidth = mlp.leftMargin + mlp.rightMargin; 125 spaceHeight = mlp.topMargin + mlp.bottomMargin; 126 left = lineX + mlp.leftMargin; 127 top = lineY + mlp.topMargin; 128 right = lineX + mlp.leftMargin + childWidth; 129 bottom = lineY + mlp.topMargin + childHeight; 130 } else { 131 left = lineX; 132 top = lineY; 133 right = lineX + childWidth; 134 bottom = lineY + childHeight; 135 } 136 spaceWidth += childWidth; 137 spaceHeight += childHeight; 138 139 if (lineUsed + spaceWidth > lineWidth) { 140 //approach the limit of width and move to next line 141 lineNumList.add(lineNum); 142 lineY += lineHeight + lineSpacing; 143 lineUsed = mPaddingLeft + mPaddingRight; 144 lineX = mPaddingLeft; 145 lineHeight = 0; 146 lineNum = 0; 147 if (childLp instanceof MarginLayoutParams) { 148 MarginLayoutParams mlp = (MarginLayoutParams) childLp; 149 left = lineX + mlp.leftMargin; 150 top = lineY + mlp.topMargin; 151 right = lineX + mlp.leftMargin + childWidth; 152 bottom = lineY + mlp.topMargin + childHeight; 153 } else { 154 left = lineX; 155 top = lineY; 156 right = lineX + childWidth; 157 bottom = lineY + childHeight; 158 } 159 } 160 child.layout(left, top, right, bottom); 161 lineNum++; 162 if (spaceHeight > lineHeight) { 163 lineHeight = spaceHeight; 164 } 165 lineUsed += spaceWidth; 166 lineX += spaceWidth; 167 } 168 // add the num of last line 169 lineNumList.add(lineNum); 170 } 171 172 /** 173 * resort child elements to use lines as few as possible 174 */ 175 public void relayoutToCompress() { 176 int childCount = this.getChildCount(); 177 if (0 == childCount) { 178 //no need to sort if FLayout has no child view 179 return; 180 } 181 int count = 0; 182 for (int i = 0; i < childCount; i++) { 183 View v = getChildAt(i); 184 if (v instanceof BlankView) { 185 //BlankView is just to make childs look in alignment, we should ignore them when we relayout 186 continue; 187 } 188 count++; 189 } 190 View[] childs = new View[count]; 191 int[] spaces = new int[count]; 192 int n = 0; 193 for (int i = 0; i < childCount; i++) { 194 View v = getChildAt(i); 195 if (v instanceof BlankView) { 196 //BlankView is just to make childs look in alignment, we should ignore them when we relayout 197 continue; 198 } 199 childs[n] = v; 200 LayoutParams childLp = v.getLayoutParams(); 201 int childWidth = v.getMeasuredWidth(); 202 if (childLp instanceof MarginLayoutParams) { 203 MarginLayoutParams mlp = (MarginLayoutParams) childLp; 204 spaces[n] = mlp.leftMargin + childWidth + mlp.rightMargin; 205 } else { 206 spaces[n] = childWidth; 207 } 208 n++; 209 } 210 int[] compressSpaces = new int[count]; 211 for (int i = 0; i < count; i++) { 212 compressSpaces[i] = spaces[i] > usefulWidth ? usefulWidth : spaces[i]; 213 } 214 sortToCompress(childs, compressSpaces); 215 this.removeAllViews(); 216 for (View v : childList) { 217 this.addView(v); 218 } 219 childList.clear(); 220 } 221 222 private void sortToCompress(View[] childs, int[] spaces) { 223 int childCount = childs.length; 224 int[][] table = new int[childCount + 1][usefulWidth + 1]; 225 for (int i = 0; i < childCount + 1; i++) { 226 for (int j = 0; j < usefulWidth; j++) { 227 table[i][j] = 0; 228 } 229 } 230 boolean[] flag = new boolean[childCount]; 231 for (int i = 0; i < childCount; i++) { 232 flag[i] = false; 233 } 234 for (int i = 1; i <= childCount; i++) { 235 for (int j = spaces[i - 1]; j <= usefulWidth; j++) { 236 table[i][j] = (table[i - 1][j] > table[i - 1][j - spaces[i - 1]] + spaces[i - 1]) ? table[i - 1][j] : table[i - 1][j - spaces[i - 1]] + spaces[i - 1]; 237 } 238 } 239 int v = usefulWidth; 240 for (int i = childCount; i > 0 && v >= spaces[i - 1]; i--) { 241 if (table[i][v] == table[i - 1][v - spaces[i - 1]] + spaces[i - 1]) { 242 flag[i - 1] = true; 243 v = v - spaces[i - 1]; 244 } 245 } 246 int rest = childCount; 247 View[] restArray; 248 int[] restSpaces; 249 for (int i = 0; i < flag.length; i++) { 250 if (flag[i] == true) { 251 childList.add(childs[i]); 252 rest--; 253 } 254 } 255 256 if (0 == rest) { 257 return; 258 } 259 restArray = new View[rest]; 260 restSpaces = new int[rest]; 261 int index = 0; 262 for (int i = 0; i < flag.length; i++) { 263 if (flag[i] == false) { 264 restArray[index] = childs[i]; 265 restSpaces[index] = spaces[i]; 266 index++; 267 } 268 } 269 table = null; 270 childs = null; 271 flag = null; 272 sortToCompress(restArray, restSpaces); 273 } 274 275 /** 276 * add some blank view to make child elements look in alignment 277 */ 278 public void relayoutToAlign() { 279 int childCount = this.getChildCount(); 280 if (0 == childCount) { 281 //no need to sort if FLayout has no child view 282 return; 283 } 284 int count = 0; 285 for (int i = 0; i < childCount; i++) { 286 View v = getChildAt(i); 287 if (v instanceof BlankView) { 288 //BlankView is just to make childs look in alignment, we should ignore them when we relayout 289 continue; 290 } 291 count++; 292 } 293 View[] childs = new View[count]; 294 int[] spaces = new int[count]; 295 int n = 0; 296 for (int i = 0; i < childCount; i++) { 297 View v = getChildAt(i); 298 if (v instanceof BlankView) { 299 //BlankView is just to make childs look in alignment, we should ignore them when we relayout 300 continue; 301 } 302 childs[n] = v; 303 LayoutParams childLp = v.getLayoutParams(); 304 int childWidth = v.getMeasuredWidth(); 305 if (childLp instanceof MarginLayoutParams) { 306 MarginLayoutParams mlp = (MarginLayoutParams) childLp; 307 spaces[n] = mlp.leftMargin + childWidth + mlp.rightMargin; 308 } else { 309 spaces[n] = childWidth; 310 } 311 n++; 312 } 313 int lineTotal = 0; 314 int start = 0; 315 this.removeAllViews(); 316 for (int i = 0; i < count; i++) { 317 if (lineTotal + spaces[i] > usefulWidth) { 318 int blankWidth = usefulWidth - lineTotal; 319 int end = i - 1; 320 int blankCount = end - start; 321 if (blankCount >= 0) { 322 if (blankCount > 0) { 323 int eachBlankWidth = blankWidth / blankCount; 324 MarginLayoutParams lp = new MarginLayoutParams(eachBlankWidth, 0); 325 for (int j = start; j < end; j++) { 326 this.addView(childs[j]); 327 BlankView blank = new BlankView(mContext); 328 this.addView(blank, lp); 329 } 330 } 331 this.addView(childs[end]); 332 start = i; 333 i--; 334 lineTotal = 0; 335 } else { 336 this.addView(childs[i]); 337 start = i + 1; 338 lineTotal = 0; 339 } 340 } else { 341 lineTotal += spaces[i]; 342 } 343 } 344 for (int i = start; i < count; i++) { 345 this.addView(childs[i]); 346 } 347 } 348 349 public void setflineSpacing(int sp) { 350 lineSpacing = sp; 351 } 352 353 /** 354 * use both of relayout methods together 355 */ 356 public void relayoutToCompressAndAlign() { 357 this.relayoutToCompress(); 358 this.relayoutToAlign(); 359 } 360 361 /** 362 * cut the FLayout to the specified num of lines 363 * 364 * @param line_num 365 */ 366 public void specifyLines(int line_num) { 367 int childNum = 0; 368 if (line_num > lineNumList.size()) { 369 line_num = lineNumList.size(); 370 } 371 for (int i = 0; i < line_num; i++) { 372 childNum += lineNumList.get(i); 373 } 374 List<View> viewList = new ArrayList<>(); 375 for (int i = 0; i < childNum; i++) { 376 viewList.add(getChildAt(i)); 377 } 378 removeAllViews(); 379 for (View v : viewList) { 380 addView(v); 381 } 382 } 383 384 @Override 385 protected LayoutParams generateLayoutParams(LayoutParams p) { 386 return new MarginLayoutParams(p); 387 } 388 389 @Override 390 public LayoutParams generateLayoutParams(AttributeSet attrs) { 391 return new MarginLayoutParams(getContext(), attrs); 392 } 393 394 @Override 395 protected LayoutParams generateDefaultLayoutParams() { 396 return new MarginLayoutParams(super.generateDefaultLayoutParams()); 397 } 398 399 class BlankView extends View { 400 401 public BlankView(Context context) { 402 super(context); 403 } 404 } 405 }
自定义圆角图片类Circle_ImageView.java:
1 package com.example.administrator.sbdemo; 2 3 import android.content.Context; 4 import android.content.res.TypedArray; 5 import android.graphics.Bitmap; 6 import android.graphics.BitmapShader; 7 import android.graphics.Canvas; 8 import android.graphics.Color; 9 import android.graphics.ColorFilter; 10 import android.graphics.Matrix; 11 import android.graphics.Paint; 12 import android.graphics.RectF; 13 import android.graphics.Shader; 14 import android.graphics.drawable.BitmapDrawable; 15 import android.graphics.drawable.ColorDrawable; 16 import android.graphics.drawable.Drawable; 17 import android.net.Uri; 18 import android.support.annotation.ColorInt; 19 import android.support.annotation.ColorRes; 20 import android.support.annotation.DrawableRes; 21 import android.util.AttributeSet; 22 import android.widget.ImageView; 23 24 25 /** 26 * Created by ${火龙裸先生} on 2016/9/5. 27 * 邮箱:791335000@qq.com 28 */ 29 public class Circle_ImageView extends ImageView { 30 private static final ScaleType SCALE_TYPE = ScaleType.CENTER_CROP; 31 32 private static final Bitmap.Config BITMAP_CONFIG = Bitmap.Config.ARGB_8888; 33 private static final int COLORDRAWABLE_DIMENSION = 2; 34 35 private static final int DEFAULT_BORDER_WIDTH = 0; 36 private static final int DEFAULT_BORDER_COLOR = Color.BLACK; 37 private static final int DEFAULT_FILL_COLOR = Color.TRANSPARENT; 38 private static final boolean DEFAULT_BORDER_OVERLAY = false; 39 40 private final RectF mDrawableRect = new RectF(); 41 private final RectF mBorderRect = new RectF(); 42 43 private final Matrix mShaderMatrix = new Matrix(); 44 private final Paint mBitmapPaint = new Paint(); 45 private final Paint mBorderPaint = new Paint(); 46 private final Paint mFillPaint = new Paint(); 47 48 private int mBorderColor = DEFAULT_BORDER_COLOR; 49 private int mBorderWidth = DEFAULT_BORDER_WIDTH; 50 private int mFillColor = DEFAULT_FILL_COLOR; 51 52 private Bitmap mBitmap; 53 private BitmapShader mBitmapShader; 54 private int mBitmapWidth; 55 private int mBitmapHeight; 56 57 private float mDrawableRadius; 58 private float mBorderRadius; 59 60 private ColorFilter mColorFilter; 61 62 private boolean mReady; 63 private boolean mSetupPending; 64 private boolean mBorderOverlay; 65 private boolean mDisableCircularTransformation; 66 67 public Circle_ImageView(Context context) { 68 super(context); 69 70 init(); 71 } 72 73 public Circle_ImageView(Context context, AttributeSet attrs) { 74 this(context, attrs, 0); 75 } 76 77 public Circle_ImageView(Context context, AttributeSet attrs, int defStyle) { 78 super(context, attrs, defStyle); 79 80 TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CircleImageView, defStyle, 0); 81 82 mBorderWidth = a.getDimensionPixelSize(R.styleable.CircleImageView_civ_border_width, DEFAULT_BORDER_WIDTH); 83 mBorderColor = a.getColor(R.styleable.CircleImageView_civ_border_color, DEFAULT_BORDER_COLOR); 84 mBorderOverlay = a.getBoolean(R.styleable.CircleImageView_civ_border_overlay, DEFAULT_BORDER_OVERLAY); 85 mFillColor = a.getColor(R.styleable.CircleImageView_civ_fill_color, DEFAULT_FILL_COLOR); 86 87 a.recycle(); 88 89 init(); 90 } 91 92 private void init() { 93 super.setScaleType(SCALE_TYPE); 94 mReady = true; 95 96 if (mSetupPending) { 97 setup(); 98 mSetupPending = false; 99 } 100 } 101 102 @Override 103 public ScaleType getScaleType() { 104 return SCALE_TYPE; 105 } 106 107 @Override 108 public void setScaleType(ScaleType scaleType) { 109 if (scaleType != SCALE_TYPE) { 110 throw new IllegalArgumentException(String.format("ScaleType %s not supported.", scaleType)); 111 } 112 } 113 114 @Override 115 public void setAdjustViewBounds(boolean adjustViewBounds) { 116 if (adjustViewBounds) { 117 throw new IllegalArgumentException("adjustViewBounds not supported."); 118 } 119 } 120 121 @Override 122 protected void onDraw(Canvas canvas) { 123 if (mDisableCircularTransformation) { 124 super.onDraw(canvas); 125 return; 126 } 127 128 if (mBitmap == null) { 129 return; 130 } 131 132 if (mFillColor != Color.TRANSPARENT) { 133 canvas.drawCircle(mDrawableRect.centerX(), mDrawableRect.centerY(), mDrawableRadius, mFillPaint); 134 } 135 canvas.drawCircle(mDrawableRect.centerX(), mDrawableRect.centerY(), mDrawableRadius, mBitmapPaint); 136 if (mBorderWidth > 0) { 137 canvas.drawCircle(mBorderRect.centerX(), mBorderRect.centerY(), mBorderRadius, mBorderPaint); 138 } 139 } 140 141 @Override 142 protected void onSizeChanged(int w, int h, int oldw, int oldh) { 143 super.onSizeChanged(w, h, oldw, oldh); 144 setup(); 145 } 146 147 @Override 148 public void setPadding(int left, int top, int right, int bottom) { 149 super.setPadding(left, top, right, bottom); 150 setup(); 151 } 152 153 @Override 154 public void setPaddingRelative(int start, int top, int end, int bottom) { 155 super.setPaddingRelative(start, top, end, bottom); 156 setup(); 157 } 158 159 public int getBorderColor() { 160 return mBorderColor; 161 } 162 163 public void setBorderColor(@ColorInt int borderColor) { 164 if (borderColor == mBorderColor) { 165 return; 166 } 167 168 mBorderColor = borderColor; 169 mBorderPaint.setColor(mBorderColor); 170 invalidate(); 171 } 172 173 /** 174 * @deprecated Use {@link #setBorderColor(int)} instead 175 */ 176 @Deprecated 177 public void setBorderColorResource(@ColorRes int borderColorRes) { 178 setBorderColor(getContext().getResources().getColor(borderColorRes)); 179 } 180 181 /** 182 * Return the color drawn behind the circle-shaped drawable. 183 * 184 * @return The color drawn behind the drawable 185 * @deprecated Fill color support is going to be removed in the future 186 */ 187 @Deprecated 188 public int getFillColor() { 189 return mFillColor; 190 } 191 192 /** 193 * Set a color to be drawn behind the circle-shaped drawable. Note that 194 * this has no effect if the drawable is opaque or no drawable is set. 195 * 196 * @param fillColor The color to be drawn behind the drawable 197 * @deprecated Fill color support is going to be removed in the future 198 */ 199 @Deprecated 200 public void setFillColor(@ColorInt int fillColor) { 201 if (fillColor == mFillColor) { 202 return; 203 } 204 205 mFillColor = fillColor; 206 mFillPaint.setColor(fillColor); 207 invalidate(); 208 } 209 210 /** 211 * Set a color to be drawn behind the circle-shaped drawable. Note that 212 * this has no effect if the drawable is opaque or no drawable is set. 213 * 214 * @param fillColorRes The color resource to be resolved to a color and 215 * drawn behind the drawable 216 * @deprecated Fill color support is going to be removed in the future 217 */ 218 @Deprecated 219 public void setFillColorResource(@ColorRes int fillColorRes) { 220 setFillColor(getContext().getResources().getColor(fillColorRes)); 221 } 222 223 public int getBorderWidth() { 224 return mBorderWidth; 225 } 226 227 public void setBorderWidth(int borderWidth) { 228 if (borderWidth == mBorderWidth) { 229 return; 230 } 231 232 mBorderWidth = borderWidth; 233 setup(); 234 } 235 236 public boolean isBorderOverlay() { 237 return mBorderOverlay; 238 } 239 240 public void setBorderOverlay(boolean borderOverlay) { 241 if (borderOverlay == mBorderOverlay) { 242 return; 243 } 244 245 mBorderOverlay = borderOverlay; 246 setup(); 247 } 248 249 public boolean isDisableCircularTransformation() { 250 return mDisableCircularTransformation; 251 } 252 253 public void setDisableCircularTransformation(boolean disableCircularTransformation) { 254 if (mDisableCircularTransformation == disableCircularTransformation) { 255 return; 256 } 257 258 mDisableCircularTransformation = disableCircularTransformation; 259 initializeBitmap(); 260 } 261 262 @Override 263 public void setImageBitmap(Bitmap bm) { 264 super.setImageBitmap(bm); 265 initializeBitmap(); 266 } 267 268 @Override 269 public void setImageDrawable(Drawable drawable) { 270 super.setImageDrawable(drawable); 271 initializeBitmap(); 272 } 273 274 @Override 275 public void setImageResource(@DrawableRes int resId) { 276 super.setImageResource(resId); 277 initializeBitmap(); 278 } 279 280 @Override 281 public void setImageURI(Uri uri) { 282 super.setImageURI(uri); 283 initializeBitmap(); 284 } 285 286 @Override 287 public void setColorFilter(ColorFilter cf) { 288 if (cf == mColorFilter) { 289 return; 290 } 291 292 mColorFilter = cf; 293 applyColorFilter(); 294 invalidate(); 295 } 296 297 @Override 298 public ColorFilter getColorFilter() { 299 return mColorFilter; 300 } 301 302 private void applyColorFilter() { 303 if (mBitmapPaint != null) { 304 mBitmapPaint.setColorFilter(mColorFilter); 305 } 306 } 307 308 private Bitmap getBitmapFromDrawable(Drawable drawable) { 309 if (drawable == null) { 310 return null; 311 } 312 313 if (drawable instanceof BitmapDrawable) { 314 return ((BitmapDrawable) drawable).getBitmap(); 315 } 316 317 try { 318 Bitmap bitmap; 319 320 if (drawable instanceof ColorDrawable) { 321 bitmap = Bitmap.createBitmap(COLORDRAWABLE_DIMENSION, COLORDRAWABLE_DIMENSION, BITMAP_CONFIG); 322 } else { 323 bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), BITMAP_CONFIG); 324 } 325 326 Canvas canvas = new Canvas(bitmap); 327 drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight()); 328 drawable.draw(canvas); 329 return bitmap; 330 } catch (Exception e) { 331 e.printStackTrace(); 332 return null; 333 } 334 } 335 336 private void initializeBitmap() { 337 if (mDisableCircularTransformation) { 338 mBitmap = null; 339 } else { 340 mBitmap = getBitmapFromDrawable(getDrawable()); 341 } 342 setup(); 343 } 344 345 private void setup() { 346 if (!mReady) { 347 mSetupPending = true; 348 return; 349 } 350 351 if (getWidth() == 0 && getHeight() == 0) { 352 return; 353 } 354 355 if (mBitmap == null) { 356 invalidate(); 357 return; 358 } 359 360 mBitmapShader = new BitmapShader(mBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); 361 362 mBitmapPaint.setAntiAlias(true); 363 mBitmapPaint.setShader(mBitmapShader); 364 365 mBorderPaint.setStyle(Paint.Style.STROKE); 366 mBorderPaint.setAntiAlias(true); 367 mBorderPaint.setColor(mBorderColor); 368 mBorderPaint.setStrokeWidth(mBorderWidth); 369 370 mFillPaint.setStyle(Paint.Style.FILL); 371 mFillPaint.setAntiAlias(true); 372 mFillPaint.setColor(mFillColor); 373 374 mBitmapHeight = mBitmap.getHeight(); 375 mBitmapWidth = mBitmap.getWidth(); 376 377 mBorderRect.set(calculateBounds()); 378 mBorderRadius = Math.min((mBorderRect.height() - mBorderWidth) / 2.0f, (mBorderRect.width() - mBorderWidth) / 2.0f); 379 380 mDrawableRect.set(mBorderRect); 381 if (!mBorderOverlay && mBorderWidth > 0) { 382 mDrawableRect.inset(mBorderWidth - 1.0f, mBorderWidth - 1.0f); 383 } 384 mDrawableRadius = Math.min(mDrawableRect.height() / 2.0f, mDrawableRect.width() / 2.0f); 385 386 applyColorFilter(); 387 updateShaderMatrix(); 388 invalidate(); 389 } 390 391 private RectF calculateBounds() { 392 int availableWidth = getWidth() - getPaddingLeft() - getPaddingRight(); 393 int availableHeight = getHeight() - getPaddingTop() - getPaddingBottom(); 394 395 int sideLength = Math.min(availableWidth, availableHeight); 396 397 float left = getPaddingLeft() + (availableWidth - sideLength) / 2f; 398 float top = getPaddingTop() + (availableHeight - sideLength) / 2f; 399 400 return new RectF(left, top, left + sideLength, top + sideLength); 401 } 402 403 private void updateShaderMatrix() { 404 float scale; 405 float dx = 0; 406 float dy = 0; 407 408 mShaderMatrix.set(null); 409 410 if (mBitmapWidth * mDrawableRect.height() > mDrawableRect.width() * mBitmapHeight) { 411 scale = mDrawableRect.height() / (float) mBitmapHeight; 412 dx = (mDrawableRect.width() - mBitmapWidth * scale) * 0.5f; 413 } else { 414 scale = mDrawableRect.width() / (float) mBitmapWidth; 415 dy = (mDrawableRect.height() - mBitmapHeight * scale) * 0.5f; 416 } 417 418 mShaderMatrix.setScale(scale, scale); 419 mShaderMatrix.postTranslate((int) (dx + 0.5f) + mDrawableRect.left, (int) (dy + 0.5f) + mDrawableRect.top); 420 421 mBitmapShader.setLocalMatrix(mShaderMatrix); 422 } 423 }
自定义圆角图片对应的attr文件属性定义(先在values文件夹下新建一个attr.xml文件):
1 <!-- 自定义圆角ImageView --> 2 <declare-styleable name="CircleImageView"> 3 <attr name="civ_border_width" format="dimension" /> 4 <attr name="civ_border_color" format="color" /> 5 <attr name="civ_border_overlay" format="boolean" /> 6 <attr name="civ_fill_color" format="color" /> 7 </declare-styleable>
自定义ListView类MyListview.java:
1 package com.example.administrator.sbdemo; 2 3 import android.content.Context; 4 import android.util.AttributeSet; 5 import android.view.MotionEvent; 6 import android.widget.ListView; 7 8 /** 9 * 参数:Created by Administrator on 2017/3/13. 10 * 类作用:Created by Administrator on 2017/3/13. 11 */ 12 public class MyListview extends ListView { 13 public MyListview(Context context) { 14 super(context); 15 } 16 17 public MyListview(Context context, AttributeSet attrs) { 18 super(context, attrs); 19 } 20 21 public MyListview(Context context, AttributeSet attrs, int defStyleAttr) { 22 super(context, attrs, defStyleAttr); 23 } 24 25 @Override 26 public boolean onInterceptTouchEvent(MotionEvent ev) { 27 return false; 28 } 29 30 @Override 31 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 32 // TODO Auto-generated method stub 33 int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, 34 MeasureSpec.AT_MOST); 35 super.onMeasure(widthMeasureSpec, expandSpec); 36 } 37 }
自定义ScrollView类MyScrollView.java:
1 package com.example.administrator.sbdemo; 2 3 import android.animation.ObjectAnimator; 4 import android.animation.ValueAnimator; 5 import android.content.Context; 6 import android.graphics.Color; 7 import android.graphics.Rect; 8 import android.util.AttributeSet; 9 import android.util.Log; 10 import android.view.View; 11 import android.view.ViewGroup; 12 import android.widget.ImageView; 13 import android.widget.ScrollView; 14 15 /** 16 * 参数:Created by Administrator on 2017/3/13. 17 * 类作用:Created by Administrator on 2017/3/13. 18 */ 19 public class MyScrollView extends ScrollView { 20 21 private ImageView mImageView; 22 private int imageHeight = 0; 23 private int imageWidth = 0; 24 private View TitleBarView; 25 26 27 public MyScrollView(Context context) { 28 super(context); 29 imageHeight = context.getResources().getDimensionPixelSize(R.dimen.size_default_height); 30 } 31 32 public MyScrollView(Context context, AttributeSet attrs) { 33 34 super(context, attrs); 35 imageHeight = context.getResources().getDimensionPixelSize(R.dimen.size_default_height); 36 37 } 38 39 public MyScrollView(Context context, AttributeSet attrs, int defStyleAttr) { 40 super(context, attrs, defStyleAttr); 41 imageHeight = context.getResources().getDimensionPixelSize(R.dimen.size_default_height); 42 } 43 44 public void setImageWidth(int width) { 45 this.imageWidth = width; 46 } 47 48 public void setZoomImageView(ImageView iv) { 49 mImageView = iv; 50 } 51 52 public void setTitleBarView(View view) { 53 this.TitleBarView = view; 54 } 55 56 @Override 57 protected void onScrollChanged(int l, int t, int oldl, int oldt) { 58 Log.i("xgr", t + "****" + imageHeight); 59 if (t <= 0) { 60 TitleBarView.setBackgroundColor(Color.argb((int) 0, 63, 81, 181));//AGB由相关工具获得,或者美工提供 61 } else if (t > 0 && t + TitleBarView.getHeight() <= imageHeight) { 62 float scale = (float) t / imageHeight; 63 float alpha = (255 * scale); 64 // 只是layout背景透明 65 TitleBarView.setBackgroundColor(Color.argb((int) alpha, 63, 81, 181)); 66 } else { 67 TitleBarView.setBackgroundColor(Color.argb((int) 255, 63, 81, 181)); 68 } 69 super.onScrollChanged(l, t, oldl, oldt); 70 } 71 72 @Override 73 protected int computeScrollDeltaToGetChildRectOnScreen(Rect rect) { 74 return 0; 75 } 76 77 78 }
最后MainActivity.java:
1 package com.example.administrator.sbdemo; 2 3 import android.animation.ObjectAnimator; 4 import android.animation.ValueAnimator; 5 import android.content.Context; 6 import android.os.Bundle; 7 import android.support.v7.app.AppCompatActivity; 8 import android.view.LayoutInflater; 9 import android.view.MotionEvent; 10 import android.view.View; 11 import android.view.ViewGroup; 12 import android.widget.AdapterView; 13 import android.widget.BaseAdapter; 14 import android.widget.ImageView; 15 import android.widget.RelativeLayout; 16 import android.widget.TextView; 17 import android.widget.Toast; 18 19 import java.text.SimpleDateFormat; 20 import java.util.ArrayList; 21 import java.util.Date; 22 import java.util.List; 23 24 import butterknife.Bind; 25 import butterknife.ButterKnife; 26 import butterknife.OnClick; 27 28 public class MainActivity extends AppCompatActivity implements View.OnTouchListener { 29 30 @Bind(R.id.img) 31 ImageView img; 32 @Bind(R.id.fl) 33 FLayout fl; 34 @Bind(R.id.lv) 35 MyListview lv; 36 @Bind(R.id.scrollView) 37 MyScrollView scrollView; 38 @Bind(R.id.backImage) 39 ImageView backImage; 40 @Bind(R.id.titleBar) 41 RelativeLayout titleBar; 42 @Bind(R.id.senP) 43 TextView senP; 44 private int imageWidth = 0; 45 // 记录首次按下位置 46 private float mFirstPosition = 0; 47 // 是否正在放大 48 private Boolean mScaling = false; 49 50 private Myadapter adapter; 51 private List<Model> data; 52 53 @Override 54 protected void onCreate(Bundle savedInstanceState) { 55 super.onCreate(savedInstanceState); 56 setContentView(R.layout.activity_main); 57 ButterKnife.bind(this); 58 initView(); 59 } 60 61 private void initView() { 62 // 获取控件 63 scrollView = (MyScrollView) findViewById(R.id.scrollView); 64 65 titleBar = (RelativeLayout) findViewById(R.id.titleBar); 66 67 img = (ImageView) findViewById(R.id.img); 68 img.post(new Runnable() { 69 @Override 70 public void run() { 71 imageWidth = img.getWidth(); 72 scrollView.setImageWidth(imageWidth); 73 74 } 75 }); 76 scrollView.setZoomImageView(img); 77 scrollView.setTitleBarView(titleBar); 78 scrollView.setOnTouchListener(this); 79 for (int i = 0; i < 8; i++) { 80 TextView tv = new TextView(this); 81 RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); 82 params.setMargins(20, 10, 20, 0); 83 tv.setLayoutParams(params); 84 tv.setPadding(20, 10, 20, 10); 85 tv.setText("标签" + i); 86 tv.setTextSize(20); 87 tv.setTextColor(getResources().getColor(android.R.color.white)); 88 tv.setBackground(getResources().getDrawable(R.drawable.lv_item_tv_bg)); 89 fl.addView(tv); 90 } 91 92 data = new ArrayList<>(); 93 for (int i = 0; i < 10; i++) { 94 Model model = new Model(); 95 model.setCode("ABCDEFG" + i); 96 model.setMessage("Click me,重要的事情说" + i + "遍"); 97 model.setMoney("交易金额¥" + i * 10); 98 model.setName("火龙裸先生+" + i); 99 model.setTime(getStringDate()); 100 data.add(model); 101 } 102 adapter = new Myadapter(data, this); 103 lv.setAdapter(adapter); 104 lv.setOnItemClickListener(new AdapterView.OnItemClickListener() { 105 @Override 106 public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) { 107 Toast.makeText(MainActivity.this, "点击了" + i, Toast.LENGTH_SHORT).show(); 108 } 109 }); 110 } 111 112 113 @OnClick(R.id.backImage) 114 public void back() { 115 Toast.makeText(this, "返回按钮", Toast.LENGTH_SHORT).show(); 116 } 117 118 @OnClick(R.id.senP) 119 public void sen() { 120 Toast.makeText(this, "发项目", Toast.LENGTH_SHORT).show(); 121 } 122 123 class Myadapter extends BaseAdapter { 124 private List<Model> data; 125 private LayoutInflater inflater; 126 127 public Myadapter(List<Model> data, Context context) { 128 this.data = data; 129 this.inflater = LayoutInflater.from(context); 130 } 131 132 @Override 133 public int getCount() { 134 if (data == null || data.size() <= 0) { 135 return 0; 136 } 137 return data.size(); 138 } 139 140 @Override 141 public Object getItem(int i) { 142 return null; 143 } 144 145 @Override 146 public long getItemId(int i) { 147 return 0; 148 } 149 150 @Override 151 public View getView(int i, View view, ViewGroup viewGroup) { 152 ViewHolder holder = null; 153 if (view == null) { 154 view = inflater.inflate(R.layout.item, viewGroup, false); 155 holder = new ViewHolder(view); 156 view.setTag(holder); 157 } else { 158 holder = (ViewHolder) view.getTag(); 159 } 160 161 holder.Code.setText(data.get(i).getCode()); 162 holder.message.setText(data.get(i).getMessage()); 163 holder.money.setText(data.get(i).getMoney()); 164 holder.time.setText(data.get(i).getTime()); 165 holder.name.setText(data.get(i).getName()); 166 167 return view; 168 } 169 170 171 class ViewHolder { 172 @Bind(R.id.id_icon) 173 Circle_ImageView idIcon; 174 @Bind(R.id.name) 175 TextView name; 176 @Bind(R.id.Code) 177 TextView Code; 178 @Bind(R.id.message) 179 TextView message; 180 @Bind(R.id.time) 181 TextView time; 182 @Bind(R.id.money) 183 TextView money; 184 185 ViewHolder(View view) { 186 ButterKnife.bind(this, view); 187 } 188 } 189 } 190 191 @Override 192 public boolean onTouch(View view, MotionEvent motionEvent) { 193 ViewGroup.LayoutParams lp = (ViewGroup.LayoutParams) img 194 .getLayoutParams(); 195 switch (motionEvent.getAction()) { 196 case MotionEvent.ACTION_UP: 197 // 手指离开后恢复图片 198 mScaling = false; 199 replyImage(); 200 break; 201 case MotionEvent.ACTION_MOVE: 202 if (!mScaling) { 203 if (scrollView.getScrollY() == 0) { 204 mFirstPosition = motionEvent.getY();// 滚动到顶部时记录位置,否则正常返回 205 } else { 206 break; 207 } 208 } 209 int distance = (int) ((motionEvent.getY() - mFirstPosition) * 0.6); // 滚动距离乘以一个系数 210 if (distance < 0) { // 当前位置比记录位置要小,正常返回 211 break; 212 } 213 214 // 处理放大 215 mScaling = true; 216 lp.width = imageWidth + distance; 217 //lp.height = (imageWidth + distance) * 9 / 16; 218 lp.height = getResources().getDimensionPixelSize(R.dimen.size_default_height) + distance; 219 img.setLayoutParams(lp); 220 return true; // 返回true表示已经完成触摸事件,不再处理 221 } 222 return false; 223 } 224 225 // 回弹动画 226 public void replyImage() { 227 final ViewGroup.LayoutParams lp = (ViewGroup.LayoutParams) img 228 .getLayoutParams(); 229 final float w = img.getLayoutParams().width;// 图片当前宽度 230 final float h = img.getLayoutParams().height;// 图片当前高度 231 final float newW = imageWidth;// 图片原宽度 232 final float newH = getResources().getDimensionPixelSize(R.dimen.size_default_height);// 图片原高度 233 234 // 设置动画 235 ValueAnimator anim = ObjectAnimator.ofFloat(0.0F, 1.0F) 236 .setDuration(200); 237 238 anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { 239 @Override 240 public void onAnimationUpdate(ValueAnimator animation) { 241 float cVal = (Float) animation.getAnimatedValue(); 242 lp.width = (int) (w - (w - newW) * cVal); 243 lp.height = (int) (h - (h - newH) * cVal); 244 img.setLayoutParams(lp); 245 } 246 }); 247 anim.start(); 248 249 } 250 251 //获取时间 252 public static String getStringDate() { 253 Date currentTime = new Date(); 254 SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 255 String dateString = formatter.format(currentTime); 256 return dateString; 257 } 258 }
所有代码放一起,代码有些多,大家可以分开各个小功能去看,都是比较简单的东西。