本程序是基於網上開源項目修改而來,具體來源忘了,懶得搜了,如果有不合適的地方,請原作者聯繫我,我會及時回覆和處理的!
該例子程序中主要包含兩個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(
0
,
0
);
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.
}
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(
0
,
0
);
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"
002.
xmlns:tools=
"http://schemas.android.com/tools"
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>
截圖: