Android 自定义ListView Item侧滑删除

本文介绍了一种自定义ListView的实现方式,包括侧滑删除和侧滑出菜单的功能。侧滑删除实现了滑动时item透明度变化及回弹动画,侧滑出菜单则展示了如何配合Item布局实现滑动显示菜单。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本程序是基于网上开源项目修改而来,具体来源忘了,懒得搜了,如果有不合适的地方,请原作者联系我,我会及时回复和处理的!

该例子程序中主要包含两个ListView,一个是实现侧滑删除,一个是侧滑出菜单,代码中的注释很全,我就不在赘述了,直接贴上核心代码和效果图。

侧滑删除ListView:

 


002. package com.example.testslidelistview;
003. import android.content.Context;
004. import android.util.AttributeSet;
005. import android.view.MotionEvent;
006. import android.view.VelocityTracker;
007. import android.view.View;
008. import android.view.ViewConfiguration;
009. import android.view.WindowManager;
010. import android.widget.AdapterView;
011. import android.widget.ListView;
012. import android.widget.Scroller;
013.  
014. /**
015. * 侧滑删除Item的ListView,此处是对网上开源的一个Listview的完善,
016. * 实现在手指滑动时item的透明度随之改变,并增加回到原位置的动画过程
017. * @author zhangshuo
018. */
019. public class SlideListView extends ListView {
020. /**
021. * 当前滑动的ListView position
022. */
023. private int slidePosition;
024. /**
025. * 手指按下X的坐标
026. */
027. private int downY;
028. /**
029. * 手指按下Y的坐标
030. */
031. private int downX;
032. /**
033. * 屏幕宽度
034. */
035. private int screenWidth;
036. /**
037. * ListView的item
038. */
039. private View itemView;
040. /**
041. * 滑动类
042. */
043. private Scroller scroller;
044. private static final int SNAP_VELOCITY = 600;
045. /**
046. * 速度追踪对象
047. */
048. private VelocityTracker velocityTracker;
049. /**
050. * 是否响应滑动,默认为不响应
051. */
052. private boolean isSlide = false;
053. /**
054. * 认为是用户滑动的最小距离
055. */
056. private int mTouchSlop;
057. /**
058. *  移除item后的回调接口
059. */
060. private RemoveListener mRemoveListener;
061. /**
062. *  标示是否移除
063. */
064. private boolean isRemove = false;
065. /**
066. * 用来指示item滑出屏幕的方向,向左或者向右,用一个枚举值来标记
067. */
068. private RemoveDirection removeDirection;
069.  
070. // 滑动删除方向的枚举值
071. public enum RemoveDirection {
072. RIGHT, LEFT, NONE;
073. }
074.  
075.  
076. public SlideListView(Context context) {
077. this(context, null);
078. }
079.  
080. public SlideListView(Context context, AttributeSet attrs) {
081. this(context, attrs, 0);
082. }
083.  
084. public SlideListView(Context context, AttributeSet attrs, int defStyle) {
085. super(context, attrs, defStyle);
086. screenWidth = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getWidth();
087. scroller = new Scroller(context);
088. mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
089. }
090.  
091. /**
092. * 设置滑动删除的回调接口
093. * @param removeListener
094. */
095. public void setRemoveListener(RemoveListener removeListener) {
096. this.mRemoveListener = removeListener;
097. }
098.  
099. /**
100. * 分发事件,主要做的是判断点击的是那个item, 以及通过postDelayed来设置响应左右滑动事件
101. */
102. @Override
103. public boolean dispatchTouchEvent(MotionEvent event) {
104. switch (event.getAction()) {
105. case MotionEvent.ACTION_DOWN: {
106. System.out.println("dispatch-->" "down");
107. addVelocityTracker(event);
108.  
109. // 假如scroller滚动还没有结束,我们直接返回
110. if (!scroller.isFinished()) {
111. return false;
112. }
113. downX = (int) event.getX();
114. downY = (int) event.getY();
115.  
116. slidePosition = pointToPosition(downX, downY);
117.  
118. // 无效的position, 不做任何处理
119. if (slidePosition == AdapterView.INVALID_POSITION) {
120. return super.dispatchTouchEvent(event);
121. }
122.  
123. // 获取我们点击的item view
124. itemView = getChildAt(slidePosition - getFirstVisiblePosition());
125. break;
126. }
127. case MotionEvent.ACTION_MOVE: {
128. System.out.println("dispatch-->" "move");
129. if (Math.abs(getScrollVelocity()) > SNAP_VELOCITY
130. || (Math.abs(event.getX() - downX) > mTouchSlop && Math
131. .abs(event.getY() - downY) < mTouchSlop)) {
132. isSlide = true;
133.  
134. }
135. break;
136. }
137. case MotionEvent.ACTION_UP:
138. recycleVelocityTracker();
139. break;
140. }
141.  
142. return super.dispatchTouchEvent(event);
143. }
144.  
145. /**
146. * 往右滑动,getScrollX()返回的是左边缘的距离,就是以View左边缘为原点到开始滑动的距离,所以向右边滑动为负值
147. */
148. private void scrollRight() {
149. removeDirection = RemoveDirection.RIGHT;
150. final int delta = (screenWidth + itemView.getScrollX());
151. // 调用startScroll方法来设置一些滚动的参数,我们在computeScroll()方法中调用scrollTo来滚动item
152. scroller.startScroll(itemView.getScrollX(), 0, -delta, 0,
153. Math.abs(delta));
154. postInvalidate(); // 刷新itemView
155. }
156.  
157. /**
158. * 向左滑动,根据上面我们知道向左滑动为正值
159. */
160. private void scrollLeft() {
161. removeDirection = RemoveDirection.LEFT;
162. final int delta = (screenWidth - itemView.getScrollX());
163. // 调用startScroll方法来设置一些滚动的参数,我们在computeScroll()方法中调用scrollTo来滚动item
164. scroller.startScroll(itemView.getScrollX(), 0, delta, 0,
165. Math.abs(delta));
166. postInvalidate(); // 刷新itemView
167. }
168.  
169. /**
170. *  滑动会原来的位置
171. */
172. private void scrollBack(){
173. removeDirection = RemoveDirection.NONE;
174. scroller.startScroll(itemView.getScrollX(), 0, -itemView.getScrollX(), 0,
175. Math.abs(itemView.getScrollX()));
176. postInvalidate(); // 刷新itemView
177. }
178.  
179. /**
180. * 根据手指滚动itemView的距离来判断是滚动到开始位置还是向左或者向右滚动
181. */
182. private void scrollByDistanceX() {
183. // 如果向左滚动的距离大于屏幕的二分之一,就让其删除
184. if (itemView.getScrollX() >= screenWidth / 2) {
185. scrollLeft();
186. else if (itemView.getScrollX() <= -screenWidth / 2) {
187. scrollRight();
188. else {
189. // 滚回到原始位置
190. scrollBack();
191. }
192.  
193. }
194.  
195. /**
196. * 处理我们拖动ListView item的逻辑
197. */
198. @Override
199. public boolean onTouchEvent(MotionEvent ev) {
200. if (isSlide && slidePosition != AdapterView.INVALID_POSITION) {
201. System.out.println("touch-->" "开始");
202. requestDisallowInterceptTouchEvent(true);
203. addVelocityTracker(ev);
204. final int action = ev.getAction();
205. int x = (int) ev.getX();
206. switch (action) {
207. case MotionEvent.ACTION_DOWN:
208. System.out.println("touch-->" "down");
209. break;
210. case MotionEvent.ACTION_MOVE:
211. System.out.println("touch-->" "move");
212. MotionEvent cancelEvent = MotionEvent.obtain(ev);
213. cancelEvent.setAction(MotionEvent.ACTION_CANCEL |
214. (ev.getActionIndex()<< MotionEvent.ACTION_POINTER_INDEX_SHIFT));
215. onTouchEvent(cancelEvent);
216.  
217. int deltaX = downX - x;
218.  
219. // 手指拖动itemView滚动, deltaX大于0向左滚动,小于0向右滚
220. itemView.scrollTo(deltaX, 0);
221. // 根据手指滑动的距离,调整透明度
222. itemView.setAlpha(1f - Math.abs((float)deltaX/screenWidth));
223.  
224. return true;  //拖动的时候ListView不滚动
225. case MotionEvent.ACTION_UP:
226. System.out.println("touch-->" "up");
227. // 手指离开的时候就不响应左右滚动
228. isSlide = false;
229. int velocityX = getScrollVelocity();
230. if (velocityX > SNAP_VELOCITY) {
231. scrollRight();
232. else if (velocityX < -SNAP_VELOCITY) {
233. scrollLeft();
234. else {
235. scrollByDistanceX();
236. }
237.  
238. recycleVelocityTracker();
239.  
240. break;
241. }
242. }
243.  
244. //否则直接交给ListView来处理onTouchEvent事件
245. return super.onTouchEvent(ev);
246. }
247.  
248. @Override
249. public void computeScroll() {
250. // 调用startScroll的时候scroller.computeScrollOffset()返回true,
251. if (scroller.computeScrollOffset()) {
252. // 让ListView item根据当前的滚动偏移量进行滚动
253. itemView.scrollTo(scroller.getCurrX(), scroller.getCurrY());
254.  
255. itemView.setAlpha(1f - Math.abs((float)scroller.getCurrX()/screenWidth));
256.  
257. postInvalidate();
258.  
259. // 滚动动画结束的时候调用回调接口
260. if (scroller.isFinished() && removeDirection != RemoveDirection.NONE) {
261. if (mRemoveListener == null) {
262. throw new NullPointerException("RemoveListener is null, we should called setRemoveListener()");
263. }
264. itemView.scrollTo(00);
265. itemView.setAlpha(1f);
266. mRemoveListener.removeItem(removeDirection, slidePosition);
267. }
268. }
269. }
270.  
271. /**
272. * 添加用户的速度跟踪器
273. *
274. * @param event
275. */
276. private void addVelocityTracker(MotionEvent event) {
277. if (velocityTracker == null) {
278. velocityTracker = VelocityTracker.obtain();
279. }
280.  
281. velocityTracker.addMovement(event);
282. }
283.  
284. /**
285. * 移除用户速度跟踪器
286. */
287. private void recycleVelocityTracker() {
288. if (velocityTracker != null) {
289. velocityTracker.recycle();
290. velocityTracker = null;
291. }
292. }
293.  
294. /**
295. * 获取X方向的滑动速度,大于0向右滑动,反之向左
296. *
297. * @return
298. */
299. private int getScrollVelocity() {
300. velocityTracker.computeCurrentVelocity(1000);
301. int velocity = (int) velocityTracker.getXVelocity();
302. return velocity;
303. }
304.  
305. /**
306. *
307. * 当ListView item滑出屏幕,回调这个接口
308. * 我们需要在回调方法removeItem()中移除该Item,然后刷新ListView
309. *
310. * @author xiaanming
311. *
312. */
313. public interface RemoveListener {
314. public void removeItem(RemoveDirection direction, int position);
315. }
316.  
317. }
侧滑菜单ListView:

 

 

001. package com.example.testslidelistview;
002.  
003. import android.content.Context;
004. import android.util.AttributeSet;
005. import android.view.MotionEvent;
006. import android.view.View;
007. import android.view.ViewConfiguration;
008. import android.widget.AdapterView;
009. import android.widget.ListView;
010. import android.widget.Scroller;
011.  
012. /**
013. * 侧向滑出菜单的ListView
014. * 使用请注意与ListView的Item的布局配合,
015. * 该效果的实现是基于在Item的布局中通过设置PaddingLeft和PaddingRight来隐藏左右菜单的,
016. * 所以使用此ListView时,请务必在布局Item时使用PaddingLeft和PaddingRight;
017. * 或者自己改写此ListView,已达到想要的实现方式
018. * @author zhangshuo
019. */
020. public class SlideListView2 extends ListView {
021.  
022. /**禁止侧滑模式*/
023. public static int MOD_FORBID = 0;
024. /**从左向右滑出菜单模式*/
025. public static int MOD_LEFT = 1;
026. /**从右向左滑出菜单模式*/
027. public static int MOD_RIGHT = 2;
028. /**左右均可以滑出菜单模式*/
029. public static int MOD_BOTH = 3;
030. /**当前的模式*/
031. private int mode = MOD_FORBID;
032. /**左侧菜单的长度*/
033. private int leftLength = 0;
034. /**右侧菜单的长度*/
035. private int rightLength = 0;
036.  
037. /**
038. * 当前滑动的ListView position
039. */
040. private int slidePosition;
041. /**
042. * 手指按下X的坐标
043. */
044. private int downY;
045. /**
046. * 手指按下Y的坐标
047. */
048. private int downX;
049. /**
050. * ListView的item
051. */
052. private View itemView;
053. /**
054. * 滑动类
055. */
056. private Scroller scroller;
057. /**
058. * 认为是用户滑动的最小距离
059. */
060. private int mTouchSlop;
061.  
062. /**
063. * 判断是否可以侧向滑动
064. */
065. private boolean canMove = false;
066. /**
067. * 标示是否完成侧滑
068. */
069. private boolean isSlided = false;
070.  
071. public SlideListView2(Context context) {
072. this(context, null);
073. }
074.  
075. public SlideListView2(Context context, AttributeSet attrs) {
076. this(context, attrs, 0);
077. }
078.  
079. public SlideListView2(Context context, AttributeSet attrs, int defStyle) {
080. super(context, attrs, defStyle);
081. scroller = new Scroller(context);
082. mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
083. }
084.  
085. /**
086. * 初始化菜单的滑出模式
087. * @param mode
088. */
089. public void initSlideMode(int mode){
090. this.mode = mode;
091. }
092.  
093. /**
094. * 处理我们拖动ListView item的逻辑
095. */
096. @Override
097. public boolean onTouchEvent(MotionEvent ev) {
098.  
099. final int action = ev.getAction();
100. int lastX = (int) ev.getX();
101.  
102. switch (action) {
103. case MotionEvent.ACTION_DOWN:
104. System.out.println("touch-->" "down");
105.  
106. /*当前模式不允许滑动,则直接返回,交给ListView自身去处理*/
107. if(this.mode == MOD_FORBID){
108. return super.onTouchEvent(ev);
109. }
110.  
111. // 如果处于侧滑完成状态,侧滑回去,并直接返回
112. if (isSlided) {
113. scrollBack();
114. return false;
115. }
116. // 假如scroller滚动还没有结束,我们直接返回
117. if (!scroller.isFinished()) {
118. return false;
119. }
120. downX = (int) ev.getX();
121. downY = (int) ev.getY();
122.  
123. slidePosition = pointToPosition(downX, downY);
124.  
125. // 无效的position, 不做任何处理
126. if (slidePosition == AdapterView.INVALID_POSITION) {
127. return super.onTouchEvent(ev);
128. }
129.  
130. // 获取我们点击的item view
131. itemView = getChildAt(slidePosition - getFirstVisiblePosition());
132.  
133. /*此处根据设置的滑动模式,自动获取左侧或右侧菜单的长度*/
134. if(this.mode == MOD_BOTH){
135. this.leftLength = -itemView.getPaddingLeft();
136. this.rightLength = -itemView.getPaddingRight();
137. }else if(this.mode == MOD_LEFT){
138. this.leftLength = -itemView.getPaddingLeft();
139. }else if(this.mode == MOD_RIGHT){
140. this.rightLength = -itemView.getPaddingRight();
141. }
142.  
143. break;
144. case MotionEvent.ACTION_MOVE:
145. System.out.println("touch-->" "move");
146.  
147. if (!canMove
148. && slidePosition != AdapterView.INVALID_POSITION
149. && (Math.abs(ev.getX() - downX) > mTouchSlop && Math.abs(ev
150. .getY() - downY) < mTouchSlop)) {
151. int offsetX = downX - lastX;
152. if(offsetX > 0 && (this.mode == MOD_BOTH || this.mode == MOD_RIGHT)){
153. /*从右向左滑*/
154. canMove = true;
155. }else if(offsetX < 0 && (this.mode == MOD_BOTH || this.mode == MOD_LEFT)){
156. /*从左向右滑*/
157. canMove = true;
158. }else{
159. canMove = false;
160. }
161. /*此段代码是为了避免我们在侧向滑动时同时出发ListView的OnItemClickListener时间*/
162. MotionEvent cancelEvent = MotionEvent.obtain(ev);
163. cancelEvent
164. .setAction(MotionEvent.ACTION_CANCEL
165. | (ev.getActionIndex() << MotionEvent.ACTION_POINTER_INDEX_SHIFT));
166. onTouchEvent(cancelEvent);
167. }
168. if (canMove) {
169. /*设置此属性,可以在侧向滑动时,保持ListView不会上下滚动*/
170. requestDisallowInterceptTouchEvent(true);
171.  
172. // 手指拖动itemView滚动, deltaX大于0向左滚动,小于0向右滚
173. int deltaX = downX - lastX;
174. if(deltaX < 0 && (this.mode == MOD_BOTH || this.mode == MOD_LEFT)){
175. /*向左滑*/
176. itemView.scrollTo(deltaX, 0);
177. }else if(deltaX > 0 && (this.mode == MOD_BOTH || this.mode == MOD_RIGHT)){
178. /*向右滑*/
179. itemView.scrollTo(deltaX, 0);
180. }else{
181. itemView.scrollTo(00);
182. }
183. return true// 拖动的时候ListView不滚动
184. }
185. case MotionEvent.ACTION_UP:
186. System.out.println("touch-->" "up");
187. if (canMove){
188. canMove = false;
189. scrollByDistanceX();
190. }
191. break;
192. }
193.  
194. // 否则直接交给ListView来处理onTouchEvent事件
195. return super.onTouchEvent(ev);
196. }
197.  
198. /**
199. * 根据手指滚动itemView的距离来判断是滚动到开始位置还是向左或者向右滚动
200. */
201. private void scrollByDistanceX() {
202. /*当前模式不允许滑动,则直接返回*/
203. if(this.mode == MOD_FORBID){
204. return;
205. }
206. if(itemView.getScrollX() > 0 && (this.mode == MOD_BOTH || this.mode == MOD_RIGHT)){
207. /*从右向左滑*/
208. if (itemView.getScrollX() >= rightLength / 2) {
209. scrollLeft();
210. }  else {
211. // 滚回到原始位置
212. scrollBack();
213. }
214. }else if(itemView.getScrollX() < 0 && (this.mode == MOD_BOTH || this.mode == MOD_LEFT)){
215. /*从左向右滑*/
216. if (itemView.getScrollX() <= -leftLength / 2) {
217. scrollRight();
218. else {
219. // 滚回到原始位置
220. scrollBack();
221. }
222. }else{
223. // 滚回到原始位置
224. scrollBack();
225. }
226.  
227. }
228.  
229. /**
230. * 往右滑动,getScrollX()返回的是左边缘的距离,就是以View左边缘为原点到开始滑动的距离,所以向右边滑动为负值
231. */
232. private void scrollRight() {
233. isSlided = true;
234. final int delta = (leftLength + itemView.getScrollX());
235. // 调用startScroll方法来设置一些滚动的参数,我们在computeScroll()方法中调用scrollTo来滚动item
236. scroller.startScroll(itemView.getScrollX(), 0, -delta, 0,
237. Math.abs(delta));
238. postInvalidate(); // 刷新itemView
239. }
240.  
241. /**
242. * 向左滑动,根据上面我们知道向左滑动为正值
243. */
244. private void scrollLeft() {
245. isSlided = true;
246. final int delta = (rightLength - itemView.getScrollX());
247. // 调用startScroll方法来设置一些滚动的参数,我们在computeScroll()方法中调用scrollTo来滚动item
248. scroller.startScroll(itemView.getScrollX(), 0, delta, 0,
249. Math.abs(delta));
250. postInvalidate(); // 刷新itemView
251. }
252.  
253. /**
254. * 滑动会原来的位置
255. */
256. private void scrollBack() {
257. isSlided = false;
258. scroller.startScroll(itemView.getScrollX(), 0, -itemView.getScrollX(),
259. 0, Math.abs(itemView.getScrollX()));
260. postInvalidate(); // 刷新itemView
261. }
262.  
263. @Override
264. public void computeScroll() {
265. // 调用startScroll的时候scroller.computeScrollOffset()返回true,
266. if (scroller.computeScrollOffset()) {
267. // 让ListView item根据当前的滚动偏移量进行滚动
268. itemView.scrollTo(scroller.getCurrX(), scroller.getCurrY());
269.  
270. postInvalidate();
271. }
272. }
273.  
274. /**
275. * 提供给外部调用,用以将侧滑出来的滑回去
276. */
277. public void slideBack() {
278. this.scrollBack();
279. }
280.  
281. }

注意侧滑菜单ListView的使用需要配合Item布局(主要是PaddingLeft和PaddingRight这两个属性),Item布局如下:

 

 

001. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
003. android:layout_width="match_parent"
004. android:layout_height="match_parent"
005. android:paddingLeft="-181dp"
006. android:paddingRight="-180dp"
007. android:background="@color/wheat"
008. android:orientation="horizontal" >
009.  
010. <LinearLayout
011. android:id="@+id/llayout_left"
012. android:layout_width="180dp"
013. android:layout_height="match_parent" >
014.  
015. <RelativeLayout
016. android:id="@+id/delete1"
017. android:layout_width="90dp"
018. android:layout_height="match_parent"
019. android:background="@color/slategray"
020. android:clickable="true" >
021.  
022. <TextView
023. android:layout_width="wrap_content"
024. android:layout_height="wrap_content"
025. android:layout_centerInParent="true"
026. android:gravity="center"
027. android:text="左删除"
028. android:textColor="@color/floralwhite"
029. android:textSize="15sp" />
030. </RelativeLayout>
031.  
032. <RelativeLayout
033. android:id="@+id/other1"
034. android:layout_width="90dp"
035. android:layout_height="match_parent"
036. android:background="@color/tomato"
037. android:clickable="true" >
038.  
039. <TextView
040. android:layout_width="wrap_content"
041. android:layout_height="wrap_content"
042. android:layout_centerInParent="true"
043. android:gravity="center"
044. android:text="左其他"
045. android:textColor="@color/floralwhite"
046. android:textSize="15sp" />
047. </RelativeLayout>
048. </LinearLayout>
049.  
050.  
051. <RelativeLayout
052. android:layout_width="match_parent"
053. android:layout_height="match_parent">
054. <LinearLayout
055. android:layout_width="match_parent"
056. android:layout_height="match_parent"
057. android:layout_toLeftOf="@+id/llayout_right"
058. android:orientation="vertical" >
059.  
060. <TextView
061. android:id="@+id/title"
062. android:layout_width="match_parent"
063. android:layout_height="wrap_content"
064. android:gravity="center_vertical"
065. android:paddingLeft="10dp"
066. android:paddingRight="10dp"
067. android:text="标题"
068. android:textColor="@color/orange"
069. android:textSize="17sp" />
070.  
071. <TextView
072. android:id="@+id/time"
073. android:layout_width="wrap_content"
074. android:layout_height="wrap_content"
075. android:layout_marginLeft="10dp"
076. android:text="时间"
077. android:textColor="@color/black"
078. android:textSize="13sp" />
079.  
080. <TextView
081. android:id="@+id/content"
082. android:layout_width="wrap_content"
083. android:layout_height="wrap_content"
084. android:layout_marginLeft="10dp"
085. android:text="内容"
086. android:textColor="@color/black"
087. android:textSize="13sp" />
088. </LinearLayout>
089.  
090. <LinearLayout
091. android:id="@+id/llayout_right"
092. android:layout_width="180dp"
093. android:layout_height="match_parent"
094. android:layout_alignParentRight="true" >
095.  
096. <RelativeLayout
097. android:id="@+id/other2"
098. android:layout_width="90dp"
099. android:layout_height="match_parent"
100. android:background="@color/slategray"
101. android:clickable="true" >
102.  
103. <TextView
104. android:layout_width="wrap_content"
105. android:layout_height="wrap_content"
106. android:layout_centerInParent="true"
107. android:gravity="center"
108. android:text="右其他"
109. android:textColor="@color/floralwhite"
110. android:textSize="15sp" />
111. </RelativeLayout>
112.  
113. <RelativeLayout
114. android:id="@+id/delete2"
115. android:layout_width="90dp"
116. android:layout_height="match_parent"
117. android:background="@color/tomato"
118. android:clickable="true" >
119.  
120. <TextView
121. android:layout_width="wrap_content"
122. android:layout_height="wrap_content"
123. android:layout_centerInParent="true"
124. android:gravity="center"
125. android:text="右删除"
126. android:textColor="@color/floralwhite"
127. android:textSize="15sp" />
128. </RelativeLayout>
129. </LinearLayout>
130. </RelativeLayout>
131.  
132.  
133. </LinearLayout>

截图:


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值