Skip to content

Commit 439cd8f

Browse files
committed
finish the edit wish function, supporting drag listview item
1 parent 96982e7 commit 439cd8f

20 files changed

Lines changed: 683 additions & 38 deletions
636 Bytes
Loading
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<!-- 强调一点,使用相对布局 -->
3+
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
4+
android:layout_width="fill_parent"
5+
android:layout_height="wrap_content">
6+
<TextView
7+
android:id="@+id/drag_list_item_text"
8+
android:layout_width="wrap_content"
9+
android:layout_height="@dimen/drag_item_normal_height"
10+
android:paddingLeft="5dip"
11+
android:layout_alignParentLeft="true"
12+
android:layout_centerVertical="true"
13+
android:gravity="center_vertical"/>
14+
<ImageView android:id="@+id/drag_list_item_image"
15+
android:src="@drawable/app_drag"
16+
android:layout_alignParentRight="true"
17+
android:layout_centerVertical="true"
18+
android:layout_width="wrap_content"
19+
android:layout_height="@dimen/drag_item_normal_height"/>
20+
</RelativeLayout>

baseworld/res/values/dimens.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<resources>
3+
<dimen name="drag_item_normal_height">48dip</dimen>
4+
</resources>
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package com.tianxia.lib.baseworld.widget;
2+
3+
import android.content.Context;
4+
import android.widget.ArrayAdapter;
5+
import android.view.View;
6+
import android.view.ViewGroup;
7+
import android.view.LayoutInflater;
8+
import android.widget.TextView;
9+
import java.util.List;
10+
11+
import com.tianxia.lib.baseworld.R;
12+
13+
public class DragListAdapter<T extends DragListAdapter.IDragable> extends ArrayAdapter<T> {
14+
public DragListAdapter(Context context, List<T> objects) {
15+
super(context, 0, objects);
16+
}
17+
18+
@Override
19+
public View getView(int position, View convertView, ViewGroup parent) {
20+
View view = convertView;
21+
if ( view == null) {
22+
//加载列表项模板
23+
view = LayoutInflater.from(getContext()).inflate(R.layout.drag_list_item, null);
24+
}
25+
26+
TextView textView = (TextView)view.findViewById(R.id.drag_list_item_text);
27+
textView.setText(getItem(position).getDisplay());
28+
return view;
29+
}
30+
31+
public interface IDragable {
32+
String getDisplay();
33+
}
34+
}
Lines changed: 245 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,245 @@
1+
package com.tianxia.lib.baseworld.widget;
2+
3+
import android.content.Context;
4+
5+
import android.graphics.Bitmap;
6+
import android.graphics.PixelFormat;
7+
8+
import android.util.AttributeSet;
9+
10+
import android.view.Gravity;
11+
import android.view.LayoutInflater;
12+
import android.view.MotionEvent;
13+
import android.view.View;
14+
import android.view.ViewConfiguration;
15+
import android.view.ViewGroup;
16+
import android.view.WindowManager;
17+
18+
import android.widget.Adapter;
19+
import android.widget.AdapterView;
20+
import android.widget.ArrayAdapter;
21+
import android.widget.ImageView;
22+
import android.widget.ListView;
23+
import android.widget.SimpleAdapter;
24+
import android.widget.TextView;
25+
26+
import com.tianxia.lib.baseworld.R;
27+
28+
import java.util.List;
29+
30+
/**
31+
* 拖拽ListView
32+
*/
33+
public class DragListView extends ListView {
34+
35+
private int mScaledTouchSlop;//判断滑动的一个距离,scroll的时候会用到
36+
37+
private ImageView mDragImageView;//被拖拽项的影像,其实就是一个ImageView
38+
private int mDragSrcPosition;//手指拖动项原始在列表中的位置
39+
private int mDragPosition;//手指拖动的时候,当前拖动项在列表中的位置
40+
41+
private int mDragPoint;//在当前数据项中的位置
42+
private int mDragOffset;//当前视图和屏幕的距离(这里只使用了y方向上)
43+
44+
private WindowManager mWindowManager;//windows窗口控制类
45+
private WindowManager.LayoutParams mWindowParams;//用于控制拖拽项的显示的参数
46+
47+
private int mUpScrollBounce;//拖动的时候,开始向上滚动的边界
48+
private int mDownScrollBounce;//拖动的时候,开始向下滚动的边界
49+
50+
public DragListView(Context context, AttributeSet attrs) {
51+
super(context, attrs);
52+
mScaledTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
53+
}
54+
55+
@Override
56+
public boolean onInterceptTouchEvent(MotionEvent ev) {
57+
//捕获down事件
58+
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
59+
int x = (int)ev.getX();
60+
int y = (int)ev.getY();
61+
62+
//选中的数据项位置,使用ListView自带的pointToPosition(x, y)方法
63+
mDragSrcPosition = mDragPosition = pointToPosition(x, y);
64+
//如果是无效位置(超出边界,分割线等位置),返回
65+
if (mDragPosition == AdapterView.INVALID_POSITION) {
66+
return super.onInterceptTouchEvent(ev);
67+
}
68+
69+
//获取选中项View
70+
//getChildAt(int position)显示display在界面的position位置的View
71+
//getFirstVisiblePosition()返回第一个display在界面的view在adapter的位置position,可能是0,也可能是4
72+
ViewGroup itemView = (ViewGroup) getChildAt(mDragPosition-getFirstVisiblePosition());
73+
74+
//mDragPoint点击位置在点击View内的相对位置
75+
//mDragOffset屏幕位置和当前ListView位置的偏移量,这里只用到y坐标上的值
76+
//这两个参数用于后面拖动的开始位置和移动位置的计算
77+
mDragPoint = y - itemView.getTop();
78+
mDragOffset = (int) (ev.getRawY() - y);
79+
80+
//获取右边的拖动图标,这个对后面分组拖拽有妙用
81+
View dragger = itemView.findViewById(R.id.drag_list_item_image);
82+
//如果在右边位置(拖拽图片左边的20px的右边区域)
83+
if (dragger != null && x > dragger.getLeft()-20) {
84+
//准备拖动
85+
//初始化拖动时滚动变量
86+
//scaledTouchSlop定义了拖动的偏差位(一般+-10)
87+
//mUpScrollBounce当在屏幕的上部(上面1/3区域)或者更上的区域,执行拖动的边界,mDownScrollBounce同理定义
88+
mUpScrollBounce = Math.min(y - mScaledTouchSlop, getHeight()/3);
89+
mDownScrollBounce = Math.max(y + mScaledTouchSlop, getHeight()*2/3);
90+
91+
//设置Drawingcache为true,获得选中项的影像bm,就是后面我们拖动的哪个头像
92+
itemView.setDrawingCacheEnabled(true);
93+
Bitmap bm = Bitmap.createBitmap(itemView.getDrawingCache());
94+
95+
//准备拖动影像(把影像加入到当前窗口,并没有拖动,拖动操作我们放在onTouchEvent()的move中执行)
96+
startDrag(bm, y);
97+
}
98+
return false;
99+
}
100+
return super.onInterceptTouchEvent(ev);
101+
}
102+
103+
/*
104+
* 触摸事件
105+
* */
106+
@Override
107+
public boolean onTouchEvent(MotionEvent ev) {
108+
//如果dragmageView为空,说明拦截事件中已经判定仅仅是点击,不是拖动,返回
109+
//如果点击的是无效位置,返回,需要重新判断
110+
if (mDragImageView != null && mDragPosition != INVALID_POSITION) {
111+
int action = ev.getAction();
112+
switch(action){
113+
case MotionEvent.ACTION_UP:
114+
int upY = (int)ev.getY();
115+
//释放拖动影像
116+
stopDrag();
117+
//放下后,判断位置,实现相应的位置删除和插入
118+
onDrop(upY);
119+
break;
120+
case MotionEvent.ACTION_MOVE:
121+
int moveY = (int)ev.getY();
122+
//拖动影像
123+
onDrag(moveY);
124+
break;
125+
default:break;
126+
}
127+
return true;
128+
}
129+
//这个返回值能够实现selected的选中效果,如果返回true则无选中效果
130+
return super.onTouchEvent(ev);
131+
}
132+
133+
/**
134+
* * 准备拖动,初始化拖动项的图像
135+
* * @param bm
136+
* * @param y
137+
* */
138+
public void startDrag(Bitmap bm ,int y){
139+
//释放影像,在准备影像的时候,防止影像没释放,每次都执行一下
140+
stopDrag();
141+
142+
mWindowParams = new WindowManager.LayoutParams();
143+
//从上到下计算y方向上的相对位置,
144+
mWindowParams.gravity = Gravity.TOP;
145+
mWindowParams.x = 0;
146+
mWindowParams.y = y - mDragPoint + mDragOffset;
147+
mWindowParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
148+
mWindowParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
149+
//下面这些参数能够帮助准确定位到选中项点击位置,照抄即可
150+
mWindowParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
151+
| WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
152+
| WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
153+
| WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
154+
mWindowParams.format = PixelFormat.TRANSLUCENT;
155+
mWindowParams.windowAnimations = 0;
156+
157+
//把影像ImagView添加到当前视图中
158+
ImageView imageView = new ImageView(getContext());
159+
imageView.setImageBitmap(bm);
160+
mWindowManager = (WindowManager)getContext().getSystemService("window");
161+
mWindowManager.addView(imageView, mWindowParams);
162+
//把影像ImageView引用到变量drawImageView,用于后续操作(拖动,释放等等)
163+
mDragImageView = imageView;
164+
}
165+
166+
/**
167+
* * 停止拖动,去除拖动项的头像
168+
* */
169+
public void stopDrag(){
170+
if (mDragImageView != null) {
171+
mWindowManager.removeView(mDragImageView);
172+
mDragImageView = null;
173+
}
174+
}
175+
176+
/**
177+
* * 拖动执行,在Move方法中执行
178+
* * @param y
179+
* */
180+
public void onDrag(int y){
181+
if (mDragImageView != null) {
182+
mWindowParams.alpha = 0.8f;
183+
mWindowParams.y = y - mDragPoint + mDragOffset;
184+
mWindowManager.updateViewLayout(mDragImageView, mWindowParams);
185+
}
186+
//为了避免滑动到分割线的时候,返回-1的问题
187+
int tempPosition = pointToPosition(0, y);
188+
if (tempPosition != INVALID_POSITION) {
189+
mDragPosition = tempPosition;
190+
}
191+
192+
//滚动
193+
int scrollHeight = 0;
194+
if (y < mUpScrollBounce) {
195+
scrollHeight = 8;//定义向上滚动8个像素,如果可以向上滚动的话
196+
} else if (y > mDownScrollBounce){
197+
scrollHeight = -8;//定义向下滚动8个像素,,如果可以向上滚动的话
198+
}
199+
200+
if (scrollHeight != 0) {
201+
//真正滚动的方法setSelectionFromTop()
202+
setSelectionFromTop(mDragPosition, getChildAt(mDragPosition-getFirstVisiblePosition()).getTop()+scrollHeight);
203+
}
204+
}
205+
206+
/*
207+
* 拖动放下的时候
208+
* @param y
209+
* */
210+
public void onDrop(int y){
211+
//获取放下位置在数据集合中position
212+
//定义临时位置变量为了避免滑动到分割线的时候,返回-1的问题,如果为-1,则不修改mDragPosition的值,急需执行,达到跳过无效位置的效果
213+
int tempPosition = pointToPosition(0, y);
214+
if (tempPosition != INVALID_POSITION) {
215+
mDragPosition = tempPosition;
216+
}
217+
218+
//超出边界处理
219+
if (y < getChildAt(0).getTop()) {
220+
//超出上边界,设为最小值位置0
221+
mDragPosition = 0;
222+
} else if (y > getChildAt(getChildCount()-1).getBottom()) {
223+
//超出下边界,设为最大值位置,注意哦,如果大于可视界面中最大的View的底部则是越下界,所以判断中用getChildCount()方法
224+
//但是最后一项在数据集合中的position是getAdapter().getCount()-1,这点要区分清除
225+
mDragPosition = getAdapter().getCount() - 1;
226+
}
227+
228+
//数据更新
229+
if (mDragPosition >= 0 && mDragPosition < getAdapter().getCount()) {
230+
if (mDropListener != null) {
231+
mDropListener.onDrop(mDragSrcPosition, mDragPosition);
232+
}
233+
}
234+
}
235+
236+
//set the drop listener
237+
public interface OnDropListener {
238+
void onDrop(int srcPosition, int destPosition);
239+
}
240+
241+
private OnDropListener mDropListener = null;
242+
public void setDropListener (OnDropListener listener) {
243+
mDropListener = listener;
244+
}
245+
}

baseworld/src/com/tianxia/lib/baseworld/widget/TagCloudInfo.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44

55
public class TagCloudInfo {
66

7+
public long _id;
78
public String title;
9+
public int sort;
810
public Rect rect;
911
public int textSize;
1012
public int color;

baseworld/src/com/tianxia/lib/baseworld/widget/TagCloudView.java

Lines changed: 14 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -74,32 +74,14 @@ public void init() {
7474
mPaint.setAntiAlias(true);
7575

7676
mRandom = new Random();
77-
setTagList();
7877
}
7978

80-
public void setTagList() {
81-
String[] result = {"坚持跑步!",
82-
"多喝水!",
83-
"早点睡觉,不熬夜!",
84-
"吃早餐!",
85-
"眼睛多转一转!",
86-
"戒烟戒酒!",
87-
"勤洗脸洗头洗澡!",
88-
"少坐着",
89-
"少坐着,多走走,常舒展运动一下",
90-
"开心就好",
91-
"给自己加油",
92-
"就是爱音乐",
93-
"拒绝懒惰的借口",
94-
"每天都是新的一天,微笑!",
95-
"保持居住环境清洁"};
96-
mTagClouds = new ArrayList<TagCloudInfo>();
97-
TagCloudInfo tagCloudInfo = null;
98-
for (String str : result) {
99-
tagCloudInfo = new TagCloudInfo();
100-
tagCloudInfo.title = str;
101-
mTagClouds.add(tagCloudInfo);
102-
}
79+
public void setTagList(List<TagCloudInfo> dataSource) {
80+
mTagClouds = dataSource;
81+
}
82+
83+
public List<TagCloudInfo> getTagList() {
84+
return mTagClouds;
10385
}
10486

10587
@Override
@@ -148,6 +130,10 @@ public void run() {
148130

149131
@Override
150132
public void onDraw(Canvas canvas) {
133+
if (mTagClouds == null) {
134+
return;
135+
}
136+
151137
mWidth = getWidth();
152138
mHeight = getHeight();
153139

@@ -300,4 +286,8 @@ private void centerVertialTagClouds() {
300286
}
301287
}
302288
}
289+
290+
public void refresh() {
291+
mFirstDraw = true;
292+
}
303293
}

healthworld/AndroidManifest.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
<!--以下属性为分发渠道ID,编码表参见本文档末附表-->
2727
<meta-data android:name="WAPS_PID" android:value="WAPS" />
2828
<activity android:name="com.tianxia.lib.baseworld.main.MainTabFrame"
29+
android:windowSoftInputMode="adjustPan"
2930
android:screenOrientation="portrait">
3031
<intent-filter >
3132
<action android:name="android.intent.action.MAIN" />
@@ -58,6 +59,9 @@
5859
<activity android:name=".favorite.FavoriteTabActivity"
5960
android:screenOrientation="portrait">
6061
</activity>
62+
<activity android:name=".favorite.FavoriteEditActivity"
63+
android:screenOrientation="portrait">
64+
</activity>
6165
<activity android:name=".setting.SettingTabActivity"
6266
android:screenOrientation="portrait">
6367
</activity>

0 commit comments

Comments
 (0)