android 循环滚动实现
登录 注册
- Java开源
- PHP开源
- JS脚本大全
- OPEN家园
- OPEN经验库
- OPEN文档
- OPEN资讯
- OPEN论坛
|
所有分类 > 开发语言与工具 > 移动开发 > Android开发
自定义android循环拖动组件
您的评价: |
| 收藏该经验 |
001 | package com.sunny.pager; |
002 |
003 | import java.util.HashMap; |
004 | import java.util.Map; |
005 |
006 | import android.app.Activity; |
007 | import android.content.Context; |
008 | import android.graphics.Bitmap; |
009 | import android.graphics.BitmapFactory; |
010 | import android.graphics.Color; |
011 | import android.os.Bundle; |
012 | import android.os.Environment; |
013 | import android.util.Log; |
014 | import android.view.MotionEvent; |
015 | import android.view.View; |
016 | import android.view.View.OnTouchListener; |
017 | import android.view.ViewGroup; |
018 | import android.view.Window; |
019 | import android.view.WindowManager; |
020 | import android.view.animation.AlphaAnimation; |
021 | import android.view.animation.Animation.AnimationListener; |
022 | import android.view.animation.AnimationSet; |
023 | import android.view.animation.ScaleAnimation; |
024 | import android.widget.BaseAdapter; |
025 | import android.widget.ImageView; |
026 | import android.widget.LinearLayout; |
027 | import android.widget.TextView; |
028 | import android.widget.VideoView; |
029 |
030 | public class ViewpagertestActivity extends Activity { |
031 | private static Context mContext; |
032 | private MyFrameLayout mGallery; |
033 | int[] color = {Color.CYAN, Color.BLUE, Color.GREEN, Color.RED, Color.GRAY, Color.YELLOW, Color.DKGRAY, |
034 | Color.LTGRAY, Color.MAGENTA}; |
035 | static String[] str = {"http://www.yoho.cn", "http://www.hibox.com/web/"}; |
036 | private int count = 9; |
037 | /** Called when the activity is first created. */ |
038 |
039 | public void onCreate(Bundle savedInstanceState) { |
040 | super.onCreate(savedInstanceState); |
041 |
042 | getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); |
043 | /** 标题是属于View的,所以窗口所有的修饰部分被隐藏后标题依然有效 */ |
044 | requestWindowFeature(Window.FEATURE_NO_TITLE); |
045 | Map<Integer, int[]> mapIndexs = new HashMap<Integer, int[]>(); |
046 | mapIndexs.put(0, new int[]{0, 1, 2}); |
047 | mapIndexs.put(1, new int[]{3, 4, 5}); |
048 | mapIndexs.put(2, new int[]{6, 7, 8}); |
049 | mGallery = new MyFrameLayout(this, mapIndexs); |
050 | setContentView(mGallery); |
051 |
052 | mContext = this; |
053 | // LinearLayout layout = (LinearLayout) findViewById(R.id.main_layout); |
054 |
055 | mGallery.setAdapter(baseAdapter); |
056 | LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, |
057 | LinearLayout.LayoutParams.FILL_PARENT); |
058 | // layout.addView(mGallery, layoutParams); |
059 | } |
060 |
061 | @Override |
062 | public boolean onTouchEvent(MotionEvent event) { |
063 | // TODO Auto-generated method stub |
064 | //requestDisallowInterceptTouchEvent(true); |
065 | Boolean falg = mGallery.onGalleryTouchEvent(event); |
066 | return falg; |
067 | } |
068 |
069 | static class ViewHolder { |
070 | // TextView tView; |
071 | LinearLayout layout; |
072 | TextView tView; |
073 | ImageView image; |
074 | VideoView video; |
075 | } |
076 | public static Bitmap decodeSampledBitmapFromResource(String iamgePath, int reqWidth, int reqHeight) { |
077 | // First decode with inJustDecodeBounds=true to check dimensions |
078 | final BitmapFactory.Options options = new BitmapFactory.Options(); |
079 | options.inJustDecodeBounds = true; |
080 | BitmapFactory.decodeFile(iamgePath, options); |
081 | // Calculate inSampleSize |
082 | options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight); |
083 | // Decode bitmap with inSampleSize set |
084 | options.inJustDecodeBounds = false; |
085 | return BitmapFactory.decodeFile(iamgePath, options); |
086 | } |
087 | public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) { |
088 | // Raw height and width of image |
089 | final int height = options.outHeight; |
090 | final int width = options.outWidth; |
091 | int inSampleSize = 1; |
092 | if (height > reqHeight || width > reqWidth) { |
093 | if (width > height) { |
094 | inSampleSize = Math.round((float) height / (float) reqHeight); |
095 | } else { |
096 | inSampleSize = Math.round((float) width / (float) reqWidth); |
097 | } |
098 | } |
099 | return inSampleSize; |
100 | } |
101 |
102 | BaseAdapter baseAdapter = new BaseAdapter() { |
103 | ViewHolder holder = new ViewHolder(); |
104 | @Override |
105 | public View getView(int position, View convertView, ViewGroup parent) { |
106 | holder.layout = new LinearLayout(mContext); |
107 | holder.layout.setOrientation(LinearLayout.VERTICAL); |
108 | holder.tView = new TextView(mContext); |
109 | holder.layout.addView(holder.tView); |
110 | if (position > 5) { |
111 | holder.tView.setText("第 3" + "屏 第" + (position - 5) + "页"); |
112 | holder.tView.setTextSize(18); |
113 | } else if (position > 2) { |
114 | holder.tView.setText("第 2" + "屏 第" + (position - 2) + "页"); |
115 | holder.tView.setTextSize(18); |
116 | } else { |
117 | holder.tView.setText("第 1" + "屏 第" + (position + 1) + "页"); |
118 | holder.tView.setTextSize(18); |
119 | } |
120 |
121 | holder.image = new ImageView(mContext); |
122 |
123 | holder.image.setImageBitmap(decodeSampledBitmapFromResource(Environment.getExternalStorageDirectory() |
124 | + "/2234567.jpg", 300, 200)); |
125 | if ((position + 1) % 2 == 0) { |
126 | LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(300, 200); |
127 | lp.setMargins(0, 0, 0, 0); |
128 |
129 | holder.layout.addView(holder.image, lp); |
130 | holder.video = new VideoView(mContext); |
131 | holder.video.setVideoPath("/mnt/sdcard/123456.mp4"); |
132 | holder.video.start(); |
133 | LinearLayout.LayoutParams lp1 = new LinearLayout.LayoutParams(300, 200); |
134 | lp1.setMargins(50, 220, 0, 0); |
135 | holder.layout.addView(holder.video, lp1); |
136 | } else { |
137 | LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(300, 200); |
138 | lp.setMargins(0, 0, 0, 0); |
139 | holder.layout.addView(holder.image, lp); |
140 |
141 | ImageView imageView = new ImageView(mContext); |
142 | imageView.setBackgroundColor(0xff123456); |
143 |
144 | LinearLayout.LayoutParams lp1 = new LinearLayout.LayoutParams(300, 200); |
145 | lp1.setMargins(0, 220, 0, 0); |
146 |
147 | /* |
148 | * imageView.setOnClickListener(new OnClickListener() { |
149 | * |
150 | * @Override public void onClick(View v) { // TODO |
151 | * Auto-generated method stub AnimationSet animation = |
152 | * getFadeInAnimation(3000, 0, null); Toast.makeText(mContext, |
153 | * "动画----开始", Toast.LENGTH_SHORT).show(); |
154 | * holder.image.startAnimation(animation); } }); |
155 | */ |
156 | AnimationSet animation = getFadeInAnimation(3000, 100, null); |
157 | holder.image.startAnimation(animation); |
158 | imageView.setOnTouchListener(new OnTouchListener() { |
159 | public boolean onTouch(View v, MotionEvent event) { |
160 | if (event.getAction() == MotionEvent.ACTION_MOVE) { |
161 | } |
162 | if (event.getAction() == MotionEvent.ACTION_DOWN) { |
163 | AnimationSet animation = getFadeInAnimation(3000, 100, null); |
164 | holder.image.startAnimation(animation); |
165 | // Toast.makeText(mContext, "动画----开始", |
166 | // Toast.LENGTH_SHORT).show(); |
167 | return false; |
168 | } |
169 |
170 | return false; |
171 | } |
172 | }); |
173 | holder.layout.addView(imageView, lp1); |
174 | } |
175 | holder.layout.setBackgroundColor(color[position]); |
176 | // holder.layout.setTag(holder); |
177 | return holder.layout; |
178 | } |
179 |
180 | @Override |
181 | public long getItemId(int position) { |
182 | // TODO Auto-generated method stub |
183 | return position; |
184 | } |
185 |
186 | @Override |
187 | public Object getItem(int position) { |
188 | // TODO Auto-generated method stub |
189 | return position; |
190 | } |
191 |
192 | @Override |
193 | public int getCount() { |
194 | // TODO Auto-generated method stub |
195 | return count; |
196 | } |
197 | }; |
198 |
199 | public AnimationSet getFadeInAnimation(long durationMillis, long delay, AnimationListener listener) { |
200 | AlphaAnimation alphaAnim = null; |
201 | ScaleAnimation scaleAnimation = null; |
202 | if (delay < 0) |
203 | delay = 0; |
204 | if (durationMillis <= 100) |
205 | durationMillis = 300; |
206 | AnimationSet animationSet = new AnimationSet(true); |
207 | alphaAnim = new AlphaAnimation(1.0f, 0.0f); |
208 | scaleAnimation = new ScaleAnimation(1.0f, 0.1f, 1.0f, 0.1f); |
209 | alphaAnim.setDuration(durationMillis); |
210 | scaleAnimation.setDuration(durationMillis); |
211 | alphaAnim.setStartOffset(delay); |
212 | scaleAnimation.setStartOffset(delay); |
213 | animationSet.addAnimation(alphaAnim); |
214 | animationSet.addAnimation(scaleAnimation); |
215 | animationSet.setFillAfter(true); |
216 | if (listener != null) |
217 | alphaAnim.setAnimationListener(listener); |
218 | Log.v("animationSet", "Get animationSet: "+animationSet.toString()); |
219 | return animationSet; |
220 | } |
221 | } |
自定义逐渐基本功能实现,现在公开源码。
其中点击触发动画事件未能解决,ontouch 的down 事件响应,但是动画就是不播放,长安才能在首页播放,希望高手给点建议:
源码:
查看源码
打印
?
001 | package com.sunny.pager; |
002 |
003 | import java.util.ArrayList; |
004 | import java.util.Map; |
005 | import java.util.Set; |
006 |
007 | import android.R.integer; |
008 | import android.content.Context; |
009 | import android.database.DataSetObserver; |
010 | import android.util.Log; |
011 | import android.view.GestureDetector; |
012 | import android.view.Gravity; |
013 | import android.view.KeyEvent; |
014 | import android.view.MotionEvent; |
015 | import android.view.View; |
016 | import android.view.ViewGroup; |
017 | import android.view.animation.Animation; |
018 | import android.view.animation.AnimationUtils; |
019 | import android.view.animation.Interpolator; |
020 | import android.view.animation.Transformation; |
021 | import android.widget.Adapter; |
022 | import android.widget.FrameLayout; |
023 | import android.widget.LinearLayout; |
024 | import android.widget.Toast; |
025 |
026 | // TODO: |
027 |
028 | // 1. In order to improve performance Cache screen bitmap and use for animation |
029 | // 2. Establish superfluous memory allocations and delay or replace with reused objects |
030 | // Probably need to make sure we are not allocating objects (strings, etc.) in loops |
031 |
032 | public class MyFrameLayout extends FrameLayout { |
033 | // Constants |
034 |
035 | private final int swipe_min_distance = 120; |
036 | private final int swipe_max_off_path = 250; |
037 | private final int swipe_threshold_veloicty = 350; |
038 |
039 | // Properties |
040 |
041 | private int mViewPaddingWidth = 0; |
042 | private int mAnimationDuration = 250; |
043 | private float mSnapBorderRatio = 0.5f; |
044 | private boolean mIsGalleryCircular = true; |
045 |
046 | // Members |
047 |
048 | private int mGalleryWidth = 0; |
049 | private int mGalleryHeight = 0; |
050 | private boolean mIsTouched = false; |
051 | private boolean mIsDragging = false; |
052 | private int[] mCurrentOffset = new int[2]; |
053 | private long mScrollTimestamp = 0; |
054 | private int mFlingDirection = 0; |
055 | private int mCurrentPosition = 0; |
056 | public int mCurrentViewNumber = 0; |
057 |
058 | private Context mContext; |
059 | private Adapter mAdapter; |
060 | private FlingGalleryView[] mViews; |
061 | private FlingGalleryAnimation mAnimation; |
062 | private GestureDetector mGestureDetector; |
063 | private Interpolator mDecelerateInterpolater; |
064 | Map<Integer, int[]> mapIndexs; |
065 | private static final int MOVE_UP_DOWN = 0; |
066 | private static final int MOVE_LEFT_RIGHT = 1; |
067 | private int MoveStyle = -1; |
068 | private boolean direction = true; |
069 |
070 | //private int h_viewnumber; |
071 | //private int v_viewnumber; |
072 | private ArrayList<Integer> _xViewNumbers=new ArrayList<Integer>(); |
073 | private ArrayList<Integer> _yViewNumbers=new ArrayList<Integer>(); |
074 | public MyFrameLayout(Context context, Map<Integer, int[]> mapIndexs) { |
075 | super(context); |
076 | this.mapIndexs = mapIndexs; |
077 | mContext = context; |
078 | mAdapter = null; |
079 |
080 | mViews = new FlingGalleryView[5]; |
081 | _xViewNumbers.add(1); |
082 | _xViewNumbers.add(0); |
083 | _xViewNumbers.add(2); |
084 | _yViewNumbers.add(3); |
085 | _yViewNumbers.add(0); |
086 | _yViewNumbers.add(4); |
087 | mViews[0] = new FlingGalleryView(0, this); |
088 | mViews[1] = new FlingGalleryView(1, this); |
089 | mViews[2] = new FlingGalleryView(2, this); |
090 | mViews[3] = new FlingGalleryView(3, this); |
091 | mViews[4] = new FlingGalleryView(4, this); |
092 | mAnimation = new FlingGalleryAnimation(); |
093 | mGestureDetector = new GestureDetector(new FlingGestureDetector()); |
094 | mDecelerateInterpolater = AnimationUtils.loadInterpolator(mContext, android.R.anim.decelerate_interpolator); |
095 |
096 | } |
097 |
098 | public void setPaddingWidth(int viewPaddingWidth) { |
099 | mViewPaddingWidth = viewPaddingWidth; |
100 | } |
101 |
102 | public void setAnimationDuration(int animationDuration) { |
103 | mAnimationDuration = animationDuration; |
104 | } |
105 |
106 | public void setSnapBorderRatio(float snapBorderRatio) { |
107 | mSnapBorderRatio = snapBorderRatio; |
108 | } |
109 |
110 | public void setIsGalleryCircular(boolean isGalleryCircular) { |
111 | if (mIsGalleryCircular != isGalleryCircular) { |
112 | mIsGalleryCircular = isGalleryCircular; |
113 |
114 | if (mCurrentPosition == getFirstPosition_RL()) { |
115 | // We need to reload the view immediately to the left to change |
116 | // it to circular view or blank |
117 | mViews[getPrevViewNumber_RL(mCurrentViewNumber)].recycleView(getPrevPosition_RL(mCurrentPosition)); |
118 | } |
119 |
120 | if (mCurrentPosition == getLastPosition_RL()) { |
121 | // We need to reload the view immediately to the right to change |
122 | // it to circular view or blank |
123 | mViews[getNextViewNumber_RL(mCurrentViewNumber)].recycleView(getNextPosition_RL(mCurrentPosition)); |
124 | } |
125 |
126 | if (mCurrentPosition == getFirstPosition_UD()) { |
127 | mViews[getPrevViewNumber_UD(mCurrentViewNumber)].recycleView(getPrevPosition_UD(mCurrentPosition)); |
128 | } |
129 | if (mCurrentPosition == getLastPosition_UD()) { |
130 | mViews[getNextViewNumber_UD(mCurrentViewNumber)].recycleView(getPrevPosition_UD(mCurrentPosition)); |
131 | } |
132 | } |
133 | } |
134 |
135 | public int getGalleryCount() { |
136 | return (mAdapter == null) ? 0 : mAdapter.getCount(); |
137 | } |
138 | private int[] getXindexAndYindex(int value){ |
139 | Set<Integer> set=mapIndexs.keySet(); |
140 | int x_index=-1; |
141 | for(Integer i : set){ |
142 | x_index++; |
143 | int[] temp=mapIndexs.get(i); |
144 | int y_index=-1; |
145 | for(int j :temp){ |
146 | y_index++; |
147 | if(j==value) |
148 | return new int[]{x_index,y_index}; |
149 | } |
150 | } |
151 | return new int[]{0,0}; |
152 |
153 | } |
154 | public int getFirstPosition_RL() { |
155 | return 0; |
156 | } |
157 |
158 | public int getLastPosition_RL() { |
159 | Integer[] vs = mapIndexs.keySet().toArray(new Integer[0]); |
160 | return vs[vs.length - 1]; |
161 | } |
162 |
163 | public int getLastPosition_All() { |
164 | return (getGalleryCount() == 0) ? 0 : getGalleryCount() - 1; |
165 | } |
166 |
167 | public int getFirstPosition_UD() { |
168 | int x_index=getXindexAndYindex(mCurrentPosition)[0]; |
169 | return mapIndexs.get(x_index)[0]; |
170 | } |
171 |
172 | public int getLastPosition_UD() { |
173 | int x_index=getXindexAndYindex(mCurrentPosition)[0]; |
174 | return mapIndexs.get(x_index)[mapIndexs.get(x_index).length - 1]; |
175 | } |
176 |
177 | private int getPrevPosition_RL(int relativePosition) { |
178 | int length = mapIndexs.keySet().size(); |
179 | int lastindex = length - 1; |
180 | int x_index=getXindexAndYindex(relativePosition)[0]; |
181 | x_index--; |
182 | if (x_index < 0) { |
183 | return mapIndexs.get(lastindex)[0]; |
184 | } else { |
185 | return mapIndexs.get(x_index)[0]; |
186 | } |
187 | } |
188 |
189 | private int getPrevPosition_UD(int relativePosition) { |
190 | int x_index=getXindexAndYindex(relativePosition)[0]; |
191 | int y_index=getXindexAndYindex(relativePosition)[1]; |
192 | int length = mapIndexs.get(x_index).length; |
193 | int lastindex = length - 1; |
194 | y_index--; |
195 | if (y_index < 0) { |
196 | return mapIndexs.get(x_index)[lastindex]; |
197 | } else { |
198 | return mapIndexs.get(x_index)[y_index]; |
199 | } |
200 | } |
201 |
202 | private int getNextPosition_RL(int relativePosition) { |
203 | int length = mapIndexs.keySet().size(); |
204 | int x_index=getXindexAndYindex(relativePosition)[0]; |
205 | int lastindex = length - 1; |
206 | x_index++; |
207 | if (x_index > lastindex) { |
208 | return mapIndexs.get(0)[0]; |
209 | } else { |
210 | return mapIndexs.get(x_index)[0]; |
211 | } |
212 | } |
213 |
214 | private int getNextPosition_UD(int relativePosition) { |
215 | int x_index=getXindexAndYindex(relativePosition)[0]; |
216 | int y_index=getXindexAndYindex(relativePosition)[1]; |
217 | int length = mapIndexs.get(x_index).length; |
218 | int lastindex = length - 1; |
219 | y_index++; |
220 | if (y_index > lastindex) { |
221 | return mapIndexs.get(x_index)[0]; |
222 | } else { |
223 | return mapIndexs.get(x_index)[y_index]; |
224 | } |
225 | } |
226 |
227 | private int getPrevViewNumber_RL(int relativeViewNumber) { |
228 | int index=_xViewNumbers.indexOf(relativeViewNumber); |
229 | index=(index == 0) ? 2 : index - 1; |
230 | return _xViewNumbers.get(index); |
231 |
232 | } |
233 |
234 | private int getNextViewNumber_RL(int relativeViewNumber) { |
235 |
236 | int index=_xViewNumbers.indexOf(relativeViewNumber); |
237 | index=(index == 2) ? 0: index + 1; |
238 | return _xViewNumbers.get(index); |
239 | // return (relativeViewNumber == 2) ? 0 : relativeViewNumber + 1; |
240 | } |
241 |
242 | private int getPrevViewNumber_UD(int relativeViewNumber) { |
243 | int index=_yViewNumbers.indexOf(relativeViewNumber); |
244 | index=(index == 0) ? 2 : index - 1; |
245 | Log.v("index-------------", index+""); |
246 | return _yViewNumbers.get(index); |
247 |
248 |
249 | } |
250 |
251 | private int getNextViewNumber_UD(int relativeViewNumber) { |
252 |
253 | int index=_yViewNumbers.indexOf(relativeViewNumber); |
254 | index=(index == 2) ? 0: index + 1; |
255 | return _yViewNumbers.get(index); |
256 | } |
257 |
258 | @Override |
259 | protected void onLayout(boolean changed, int left, int top, int right, int bottom) { |
260 | super.onLayout(changed, left, top, right, bottom); |
261 |
262 | // Calculate our view width |
263 | mGalleryWidth = (right - left); |
264 | mGalleryHeight = (bottom - top); |
265 | if (changed == true) { |
266 | // Position views at correct starting offsets |
267 | mViews[0].setOffset(0, 0, mCurrentViewNumber); |
268 | mViews[1].setOffset(0, 0, mCurrentViewNumber); |
269 | mViews[2].setOffset(0, 0, mCurrentViewNumber); |
270 | mViews[3].setOffset(0, 0, mCurrentViewNumber); |
271 | mViews[4].setOffset(0, 0, mCurrentViewNumber); |
272 | } |
273 | } |
274 |
275 | DataSetObserver observer = new DataSetObserver() { |
276 | public void onChanged() { |
277 | // mCurrentPosition = 0; |
278 | // mCurrentViewNumber = 0; |
279 | // Load the initial views from adapter |
280 | mViews[0].recycleView(0); |
281 | mViews[1].recycleView(getNextPosition_RL(0)); |
282 | mViews[2].recycleView(getPrevPosition_RL(0)); |
283 | mViews[3].recycleView(getNextPosition_UD(0)); |
284 | mViews[4].recycleView(getPrevPosition_UD(0)); |
285 | // Position views at correct starting offsets |
286 | mViews[0].setOffset(0, 0, 0); |
287 | mViews[1].setOffset(0, 0, 0); |
288 | mViews[2].setOffset(0, 0, 0); |
289 | mViews[3].setOffset(0, 0, 0); |
290 | mViews[4].setOffset(0, 0, 0); |
291 | mViews[mCurrentViewNumber].requestFocus(); |
292 | } |
293 | }; |
294 |
295 | public void setAdapter(Adapter adapter) { |
296 | if (null != mAdapter && adapter != null && mAdapter.equals(adapter)) { |
297 | mAdapter.unregisterDataSetObserver(observer); |
298 | } |
299 | mAdapter = adapter; |
300 |
301 | mAdapter.registerDataSetObserver(observer); |
302 |
303 | mCurrentPosition = 0; |
304 | mCurrentViewNumber = 0; |
305 |
306 | // Load the initial views from adapter |
307 | mViews[0].recycleView(mCurrentPosition); |
308 | mViews[1].recycleView(getPrevPosition_RL(mCurrentPosition)); |
309 | mViews[2].recycleView(getNextPosition_RL(mCurrentPosition)); |
310 | mViews[3].recycleView(getPrevPosition_UD(mCurrentPosition)); |
311 | mViews[4].recycleView(getNextPosition_UD(mCurrentPosition)); |
312 | // Position views at correct starting offsets |
313 | mViews[0].setOffset(0, 0, mCurrentViewNumber); |
314 | mViews[1].setOffset(0, 0, mCurrentViewNumber); |
315 | mViews[2].setOffset(0, 0, mCurrentViewNumber); |
316 | mViews[3].setOffset(0, 0, mCurrentViewNumber); |
317 | mViews[4].setOffset(0, 0, mCurrentViewNumber); |
318 | } |
319 |
320 | private int getViewOffset(int viewNumber, int relativeViewNumber) { |
321 |
322 | int offsetWidth = mGalleryWidth + mViewPaddingWidth; |
323 | // Position the previous view one measured width to left |
324 | if (viewNumber == getPrevViewNumber_RL(relativeViewNumber)) { |
325 | return offsetWidth; |
326 | } |
327 | // Position the next view one measured width to the right |
328 | if (viewNumber == getNextViewNumber_RL(relativeViewNumber)) { |
329 | return offsetWidth * -1; |
330 | } |
331 | int offsetHeight = mGalleryHeight + mViewPaddingWidth; |
332 | // Position the previous view one measured width to left |
333 | if (viewNumber == (getPrevViewNumber_UD(relativeViewNumber))) { |
334 | return offsetHeight; |
335 | } |
336 | // Position the next view one measured width to the right |
337 | int num = getNextViewNumber_UD(relativeViewNumber); |
338 | if (viewNumber == (num)) { |
339 | return offsetHeight * -1; |
340 | } |
341 | return 0; |
342 | } |
343 |
344 | public void movePrevious_RL() { |
345 | // Slide to previous view |
346 | mFlingDirection = 1; |
347 | processGesture(); |
348 | } |
349 |
350 | public void moveNext_RL() { |
351 | // Slide to next view |
352 | mFlingDirection = -1; |
353 | processGesture(); |
354 | } |
355 |
356 | public void movePrevious_UD() { |
357 | // Slide to previous view |
358 | mFlingDirection = 2; |
359 | processGesture(); |
360 | } |
361 |
362 | public void moveNext_UD() { |
363 | // Slide to next view |
364 | mFlingDirection = -2; |
365 | processGesture(); |
366 | } |
367 |
368 | @Override |
369 | public boolean onKeyDown(int keyCode, KeyEvent event) { |
370 | switch (keyCode) { |
371 | case KeyEvent.KEYCODE_DPAD_LEFT : |
372 | movePrevious_RL(); |
373 | MoveStyle = MOVE_LEFT_RIGHT; |
374 | return true; |
375 |
376 | case KeyEvent.KEYCODE_DPAD_RIGHT : |
377 | moveNext_RL(); |
378 | MoveStyle = MOVE_LEFT_RIGHT; |
379 | return true; |
380 | case KeyEvent.KEYCODE_DPAD_UP : |
381 | movePrevious_UD(); |
382 | MoveStyle = MOVE_UP_DOWN; |
383 | return true; |
384 |
385 | case KeyEvent.KEYCODE_DPAD_DOWN : |
386 | moveNext_UD(); |
387 | MoveStyle = MOVE_UP_DOWN; |
388 | return true; |
389 |
390 | case KeyEvent.KEYCODE_DPAD_CENTER : |
391 | case KeyEvent.KEYCODE_ENTER : |
392 | } |
393 |
394 | return super.onKeyDown(keyCode, event); |
395 | } |
396 |
397 | public boolean onGalleryTouchEvent(MotionEvent event) { |
398 | // TODO Auto-generated method stub |
399 | switch (event.getAction()) { |
400 | case MotionEvent.ACTION_DOWN : { |
401 | mLastMotionX = event.getX(); |
402 | mLastMotionY = event.getY(); |
403 | break; |
404 | } |
405 | case MotionEvent.ACTION_MOVE : { |
406 | final float x = event.getX();; |
407 | final float dx = x - mLastMotionX; |
408 | final float xDiff = Math.abs(dx); |
409 | final float y = event.getY(); |
410 | final float yDiff = Math.abs(y - mLastMotionY); |
411 | if (xDiff > yDiff) { |
412 | MoveStyle = MOVE_LEFT_RIGHT; |
413 | } else { |
414 | if (yDiff > xDiff) { |
415 | MoveStyle = MOVE_UP_DOWN; |
416 | } |
417 | } |
418 | break; |
419 | } |
420 | } |
421 | boolean consumed=false; |
422 | if(direction){ |
423 | consumed = mGestureDetector.onTouchEvent(event); |
424 | } |
425 | if (event.getAction() == MotionEvent.ACTION_UP) { |
426 | //Toast.makeText(mContext, "ACTION_UP", Toast.LENGTH_SHORT).show(); |
427 | if (mIsTouched || mIsDragging) { |
428 |
429 | direction = false; |
430 | processScrollSnap(); |
431 | processGesture(); |
432 | Toast.makeText(mContext, "processGesture", Toast.LENGTH_SHORT).show(); |
433 | Log.v("ViewNumbers", "_xViewNumbers :"+ _xViewNumbers.get(0)+ _xViewNumbers.get(1)+ _xViewNumbers.get(2)+ |
434 | "_yViewNumbers :"+ _yViewNumbers.get(0)+ _yViewNumbers.get(1)+ _yViewNumbers.get(2) ); |
435 | } |
436 | } |
437 | //Toast.makeText(mContext, "consumed : "+consumed, Toast.LENGTH_SHORT).show(); |
438 | return consumed; |
439 | } |
440 | int recyclePositon; |
441 | int recycleViewNumber; |
442 |
443 | void processGesture() { |
444 | int newViewNumber = mCurrentViewNumber; |
445 | int reloadViewNumber = 0; |
446 | int reloadPosition = 0; |
447 | int reloadViewNumber_up = 0; |
448 | int reloadPosition_up = 0; |
449 | int reloadViewNumber_down = 0; |
450 | int reloadPosition_down = 0; |
451 |
452 | int reloadViewNumber_r = 0; |
453 | int reloadPosition_r = 0; |
454 | int reloadViewNumber_l = 0; |
455 | int reloadPosition_l = 0; |
456 | mIsTouched = false; |
457 | mIsDragging = false; |
458 |
459 | if (mFlingDirection == 1) { |
460 | if (mCurrentPosition > getFirstPosition_RL() || mIsGalleryCircular == true) { |
461 | // Determine previous view and outgoing view to recycle |
462 | newViewNumber = getPrevViewNumber_RL(mCurrentViewNumber); |
463 | mCurrentPosition = getPrevPosition_RL(mCurrentPosition); |
464 |
465 | recycleViewNumber=mCurrentViewNumber; |
466 | recyclePositon=getNextPosition_RL(mCurrentPosition); |
467 |
468 | reloadViewNumber = getNextViewNumber_RL(mCurrentViewNumber); |
469 | reloadPosition = getPrevPosition_RL(mCurrentPosition); |
470 |
471 | reloadPosition_up = getPrevPosition_UD(mCurrentPosition); |
472 | reloadViewNumber_up = getPrevViewNumber_UD(mCurrentViewNumber); |
473 |
474 | reloadPosition_down = getNextPosition_UD(mCurrentPosition); |
475 | reloadViewNumber_down = getNextViewNumber_UD(mCurrentViewNumber); |
476 |
477 | int pre=getPrevViewNumber_RL(newViewNumber); |
478 | int next=getNextViewNumber_RL(newViewNumber); |
479 |
480 | _xViewNumbers.set(0, pre); |
481 | _xViewNumbers.set(1, newViewNumber); |
482 | _xViewNumbers.set(2, next); |
483 | _yViewNumbers.set(1, newViewNumber); |
484 | } |
485 | } |
486 | if (mFlingDirection == 2) { |
487 | if (mCurrentPosition > getFirstPosition_UD() || mIsGalleryCircular == true) { |
488 | // Determine previous view and outgoing view to recycle |
489 | newViewNumber = getPrevViewNumber_UD(mCurrentViewNumber); |
490 | mCurrentPosition = getPrevPosition_UD(mCurrentPosition); |
491 | reloadViewNumber = getNextViewNumber_UD(mCurrentViewNumber); |
492 | reloadPosition = getPrevPosition_UD(mCurrentPosition); |
493 |
494 | reloadPosition_r = getPrevPosition_RL(mCurrentPosition); |
495 | reloadViewNumber_r = getPrevViewNumber_RL(mCurrentViewNumber); |
496 |
497 | reloadPosition_l = getNextPosition_RL(mCurrentPosition); |
498 | reloadViewNumber_l = getNextViewNumber_RL(mCurrentViewNumber); |
499 |
500 |
501 | int pre=getPrevViewNumber_UD(newViewNumber); |
502 | int next=getNextViewNumber_UD(newViewNumber); |
503 |
504 | _yViewNumbers.set(0, pre); |
505 | _yViewNumbers.set(1, newViewNumber); |
506 | _yViewNumbers.set(2, next); |
507 | _xViewNumbers.set(1, newViewNumber); |
508 | } |
509 | } |
510 |
511 | if (mFlingDirection == -1) { |
512 | if (mCurrentPosition < getLastPosition_RL() || mIsGalleryCircular == true) { |
513 | // Determine the next view and outgoing view to recycle |
514 | newViewNumber = getNextViewNumber_RL(mCurrentViewNumber); |
515 | mCurrentPosition = getNextPosition_RL(mCurrentPosition); |
516 |
517 | recycleViewNumber=mCurrentViewNumber; |
518 | recyclePositon=getPrevPosition_RL(mCurrentPosition); |
519 |
520 | reloadViewNumber = getPrevViewNumber_RL(mCurrentViewNumber); |
521 | reloadPosition = getNextPosition_RL(mCurrentPosition); |
522 |
523 | reloadPosition_up = getPrevPosition_UD(mCurrentPosition); |
524 | reloadViewNumber_up =getPrevViewNumber_UD(mCurrentViewNumber) ; |
525 |
526 | reloadPosition_down = getNextPosition_UD(mCurrentPosition); |
527 | reloadViewNumber_down = getNextViewNumber_UD(mCurrentViewNumber); |
528 |
529 | int pre=getPrevViewNumber_RL(newViewNumber); |
530 | int next=getNextViewNumber_RL(newViewNumber); |
531 |
532 | _xViewNumbers.set(0, pre); |
533 | _xViewNumbers.set(1, newViewNumber); |
534 | _xViewNumbers.set(2, next); |
535 | _yViewNumbers.set(1, newViewNumber); |
536 |
537 |
538 | } |
539 | } |
540 |
541 | if (mFlingDirection == -2) { |
542 | if (mCurrentPosition < getLastPosition_UD() || mIsGalleryCircular == true) { |
543 | // Determine the next view and outgoing view to recycle |
544 | newViewNumber = getNextViewNumber_UD(mCurrentViewNumber); |
545 | mCurrentPosition = getNextPosition_UD(mCurrentPosition); |
546 |
547 | reloadViewNumber = getPrevViewNumber_UD(mCurrentViewNumber); |
548 | reloadPosition = getNextPosition_UD(mCurrentPosition); |
549 |
550 | reloadPosition_r = getPrevPosition_RL(mCurrentPosition); |
551 | reloadViewNumber_r = getPrevViewNumber_RL(mCurrentViewNumber); |
552 |
553 | reloadPosition_l = getNextPosition_RL(mCurrentPosition); |
554 | reloadViewNumber_l = getNextViewNumber_RL(mCurrentViewNumber); |
555 |
556 | int pre=getPrevViewNumber_UD(newViewNumber); |
557 | int next=getNextViewNumber_UD(newViewNumber); |
558 |
559 | _yViewNumbers.set(0, pre); |
560 | _yViewNumbers.set(1, newViewNumber); |
561 | _yViewNumbers.set(2, next); |
562 | _xViewNumbers.set(1, newViewNumber); |
563 | } |
564 | } |
565 |
566 | if (newViewNumber != mCurrentViewNumber) { |
567 | mCurrentViewNumber = newViewNumber; |
568 | // Reload outgoing view from adapter in new position |
569 | if (MoveStyle == MOVE_LEFT_RIGHT) { |
570 | mViews[reloadViewNumber].recycleView(reloadPosition); |
571 | mViews[reloadViewNumber_up].recycleView(reloadPosition_up); |
572 | mViews[reloadViewNumber_down].recycleView(reloadPosition_down); |
573 | } else if (MoveStyle == MOVE_UP_DOWN) { |
574 | mViews[reloadViewNumber].recycleView(reloadPosition); |
575 | mViews[reloadViewNumber_r].recycleView(reloadPosition_r); |
576 | mViews[reloadViewNumber_l].recycleView(reloadPosition_l); |
577 | } |
578 | } |
579 |
580 | // Ensure input focus on the current view |
581 | mViews[mCurrentViewNumber].requestFocus(); |
582 |
583 | // Run the slide animations for view transitions |
584 | mAnimation.prepareAnimation(mCurrentViewNumber); |
585 | this.startAnimation(mAnimation); |
586 |
587 | // Reset fling state |
588 | mFlingDirection = 0; |
589 | } |
590 |
591 | void processScrollSnap() { |
592 | // Snap to next view if scrolled passed snap position |
593 | if (MoveStyle == MOVE_LEFT_RIGHT) { |
594 | float rollEdgeWidth = mGalleryWidth * mSnapBorderRatio; |
595 | int rollOffset = mGalleryWidth - (int) rollEdgeWidth; |
596 | int currentOffset = mViews[mCurrentViewNumber].getCurrentOffset()[0]; |
597 | if (currentOffset <= rollOffset * -1) { |
598 | // Snap to previous view |
599 | mFlingDirection = 1; |
600 | } |
601 | if (currentOffset >= rollOffset) { |
602 | // Snap to next view |
603 | mFlingDirection = -1; |
604 | } |
605 | } else if (MoveStyle == MOVE_UP_DOWN) { |
606 |
607 | float rollEdgeHeight = mGalleryHeight * mSnapBorderRatio; |
608 | int rollOffset_Y = mGalleryHeight - (int) rollEdgeHeight; |
609 | int currentOffset_Y = mViews[mCurrentViewNumber].getCurrentOffset()[1]; |
610 | if (currentOffset_Y <= rollOffset_Y * -1) { |
611 | // Snap to previous view |
612 | mFlingDirection = 2; |
613 | } |
614 | if (currentOffset_Y >= rollOffset_Y) { |
615 | // Snap to next view |
616 | mFlingDirection = -2; |
617 | } |
618 | } |
619 | } |
620 |
621 | private class FlingGalleryView { |
622 | private int mViewNumber; |
623 | private FrameLayout mParentLayout; |
624 |
625 | private FrameLayout mInvalidLayout = null; |
626 | private LinearLayout mInternalLayout = null; |
627 | private View mExternalView = null; |
628 |
629 | public FlingGalleryView(int viewNumber, FrameLayout parentLayout) { |
630 | mViewNumber = viewNumber; |
631 | mParentLayout = parentLayout; |
632 |
633 | // Invalid layout is used when outside gallery |
634 | mInvalidLayout = new FrameLayout(mContext); |
635 | LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, |
636 | LayoutParams.FILL_PARENT); |
637 | lp.gravity = Gravity.CENTER; |
638 | mInvalidLayout.setLayoutParams(lp); |
639 |
640 | // Internal layout is permanent for duration |
641 | mInternalLayout = new LinearLayout(mContext); |
642 |
643 | mInternalLayout.setLayoutParams(lp); |
644 | mInternalLayout.setPersistentDrawingCache(ViewGroup.PERSISTENT_ALL_CACHES); |
645 | mParentLayout.addView(mInternalLayout, lp); |
646 | } |
647 |
648 | public void recycleView(int newPosition) { |
649 | if (mExternalView != null) { |
650 | mInternalLayout.removeView(mExternalView); |
651 | } |
652 |
653 | if (mAdapter != null) { |
654 | if (newPosition >= 0 && newPosition <= getLastPosition_All()) { |
655 | mExternalView = mAdapter.getView(newPosition, mExternalView, mInternalLayout); |
656 | } else { |
657 | mExternalView = mInvalidLayout; |
658 | } |
659 | } |
660 |
661 | if (mExternalView != null) { |
662 | mInternalLayout.addView(mExternalView, new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, |
663 | LayoutParams.FILL_PARENT)); |
664 | } |
665 | } |
666 |
667 | public void setOffset(int xOffset, int yOffset, int relativeViewNumber) { |
668 | // Scroll the target view relative to its own position relative to |
669 | // currently displayed view |
670 | int distance = getViewOffset(mViewNumber, relativeViewNumber); |
671 | int x=mGalleryWidth + mViewPaddingWidth; |
672 | int y=mGalleryHeight + mViewPaddingWidth; |
673 | if(Math.abs(distance)==x){ |
674 | mInternalLayout.scrollTo(distance + xOffset, yOffset); |
675 | }else if(Math.abs(distance)==y){ |
676 | mInternalLayout.scrollTo(xOffset, distance + yOffset); |
677 | }else if(Math.abs(distance)==0){ |
678 | mInternalLayout.scrollTo(xOffset, yOffset); |
679 | } |
680 | Log.v("Position", "mViewNumber: " + mViewNumber + " mCurrentViewNumber: " + mCurrentViewNumber+ " distance: " + distance); |
681 |
682 | } |
683 |
684 | public int[] getCurrentOffset() { |
685 | // Return the current scroll position |
686 | return new int[]{mInternalLayout.getScrollX(), mInternalLayout.getScrollY()}; |
687 | } |
688 |
689 | public void requestFocus() { |
690 | mInternalLayout.setFocusable(true); |
691 | mInternalLayout.setFocusableInTouchMode(true); |
692 | mInternalLayout.requestFocus(); |
693 | } |
694 | } |
695 |
696 | private class FlingGalleryAnimation extends Animation { |
697 | private boolean mIsAnimationInProgres; |
698 | private int mRelativeViewNumber; |
699 | private int mInitialOffset; |
700 | private int mTargetOffset; |
701 | private int mTargetDistance; |
702 |
703 | public FlingGalleryAnimation() { |
704 | mIsAnimationInProgres = false; |
705 | mRelativeViewNumber = 0; |
706 | mInitialOffset = 0; |
707 | mTargetOffset = 0; |
708 | mTargetDistance = 0; |
709 | } |
710 |
711 |
712 | @Override |
713 | public boolean getFillAfter() { |
714 | // TODO Auto-generated method stub |
715 | mViews[recycleViewNumber].recycleView(recyclePositon); |
716 | direction = true; |
717 | boolean falg=super.getFillAfter(); |
718 | return falg; |
719 | } |
720 |
721 |
722 | public void prepareAnimation(int relativeViewNumber) { |
723 | // If we are animating relative to a new view |
724 | if (mRelativeViewNumber != relativeViewNumber) { |
725 | if (mIsAnimationInProgres == true) { |
726 | // We only have three views so if requested again to animate |
727 | // in same direction we must snap |
728 | int newDirection=0; |
729 | int animDirection = (mTargetDistance < 0) ? 1 : -1; |
730 | if (MoveStyle == MOVE_LEFT_RIGHT) { |
731 | newDirection = (relativeViewNumber == getPrevViewNumber_RL(mRelativeViewNumber)) ? 1 : -1; |
732 | // If animation in same direction |
733 | if (animDirection == newDirection) { |
734 | // Ran out of time to animate so snap to the target |
735 | // offset |
736 | mViews[_xViewNumbers.get(0)].setOffset(mTargetOffset, 0, mRelativeViewNumber); |
737 | mViews[_xViewNumbers.get(1)].setOffset(mTargetOffset, 0, mRelativeViewNumber); |
738 | mViews[_xViewNumbers.get(2)].setOffset(mTargetOffset, 0, mRelativeViewNumber); |
739 | } |
740 | } else if (MoveStyle == MOVE_UP_DOWN) { |
741 | newDirection = (relativeViewNumber == getPrevViewNumber_UD(mRelativeViewNumber)) ? 1 : -1; |
742 | if (animDirection == newDirection) { |
743 | // Ran out of time to animate so snap to the target |
744 | // offset |
745 | mViews[_yViewNumbers.get(0)].setOffset(0, mTargetOffset, mRelativeViewNumber); |
746 | mViews[_yViewNumbers.get(1)].setOffset(0, mTargetOffset, mRelativeViewNumber); |
747 | mViews[_yViewNumbers.get(2)].setOffset(0, mTargetOffset, mRelativeViewNumber); |
748 | } |
749 | } |
750 |
751 | } |
752 |
753 | // Set relative view number for animation |
754 | mRelativeViewNumber = relativeViewNumber; |
755 | } |
756 |
757 | // Note: In this implementation the targetOffset will always be zero |
758 | // as we are centering the view; but we include the calculations of |
759 | // targetOffset and targetDistance for use in future implementations |
760 | if (MoveStyle == MOVE_LEFT_RIGHT) { |
761 | mInitialOffset = mViews[mRelativeViewNumber].getCurrentOffset()[0]; |
762 | } else if (MoveStyle == MOVE_UP_DOWN) { |
763 | mInitialOffset = mViews[mRelativeViewNumber].getCurrentOffset()[1]; |
764 | } |
765 | mTargetOffset = getViewOffset(mRelativeViewNumber, mRelativeViewNumber); |
766 | mTargetDistance = mTargetOffset - mInitialOffset; |
767 |
768 | // Configure base animation properties |
769 | this.setDuration(mAnimationDuration); |
770 | this.setInterpolator(mDecelerateInterpolater); |
771 |
772 | // Start/continued animation |
773 | mIsAnimationInProgres = true; |
774 | } |
775 |
776 | @Override |
777 | protected void applyTransformation(float interpolatedTime, Transformation transformation) { |
778 | // Ensure interpolatedTime does not over-shoot then calculate new |
779 | // offset |
780 | interpolatedTime = (interpolatedTime > 1.0f) ? 1.0f : interpolatedTime; |
781 | int offset = mInitialOffset + (int) (mTargetDistance * interpolatedTime); |
782 |
783 | for (int viewNumber = 0; viewNumber < 5; viewNumber++) { |
784 | // Only need to animate the visible views as the other view will |
785 | // always be off-screen |
786 |
787 | if (MoveStyle == MOVE_LEFT_RIGHT) { |
788 | if ((mTargetDistance > 0 && viewNumber != getNextViewNumber_RL(mRelativeViewNumber)) |
789 | || (mTargetDistance < 0 && viewNumber != getPrevViewNumber_RL(mRelativeViewNumber))) { |
790 | mViews[viewNumber].setOffset(offset, 0, mRelativeViewNumber); |
791 | } |
792 | } else if (MoveStyle == MOVE_UP_DOWN ) { |
793 | if ((mTargetDistance > 0 && viewNumber != getNextViewNumber_UD(mRelativeViewNumber)) |
794 | || (mTargetDistance < 0 && viewNumber != getPrevViewNumber_UD(mRelativeViewNumber))) { |
795 | mViews[viewNumber].setOffset(0, offset, mRelativeViewNumber); |
796 | } |
797 | } |
798 | } |
799 | } |
800 |
801 | @Override |
802 | public boolean getTransformation(long currentTime, Transformation outTransformation) { |
803 | if (super.getTransformation(currentTime, outTransformation) == false) { |
804 | // Perform final adjustment to offsets to cleanup animation |
805 | Log.v("mTargetOffset", "mTargetOffset: " + mTargetOffset); |
806 | if (MoveStyle == MOVE_LEFT_RIGHT) { |
807 |
808 | mViews[_xViewNumbers.get(0)].setOffset(mTargetOffset, 0, mRelativeViewNumber); |
809 | mViews[_xViewNumbers.get(1)].setOffset(mTargetOffset, 0, mRelativeViewNumber); |
810 | mViews[_xViewNumbers.get(2)].setOffset(mTargetOffset, 0, mRelativeViewNumber); |
811 |
812 | } else if (MoveStyle == MOVE_UP_DOWN) { |
813 | mViews[_yViewNumbers.get(0)].setOffset(0, mTargetOffset, mRelativeViewNumber); |
814 | mViews[_yViewNumbers.get(1)].setOffset(0, mTargetOffset, mRelativeViewNumber); |
815 | mViews[_yViewNumbers.get(2)].setOffset(0, mTargetOffset, mRelativeViewNumber); |
816 | } |
817 | // Reached the animation target |
818 | mIsAnimationInProgres = false; |
819 |
820 | return false; |
821 | } |
822 |
823 | // Cancel if the screen touched |
824 | if (mIsTouched || mIsDragging) { |
825 | // Note that at this point we still consider ourselves to be |
826 | // animating |
827 | // because we have not yet reached the target offset; its just |
828 | // that the |
829 | // user has temporarily interrupted the animation with a touch |
830 | // gesture |
831 |
832 | return false; |
833 | } |
834 |
835 | return true; |
836 | } |
837 | } |
838 |
839 | float mLastMotionX = 0; |
840 | float mLastMotionY = 0; |
841 |
842 | // int firstx = 0; |
843 | private class FlingGestureDetector extends GestureDetector.SimpleOnGestureListener { |
844 | @Override |
845 | public boolean onDown(MotionEvent e) { |
846 | // firstx = (int) e.getX(); |
847 | // Stop animation |
848 | //mIsTouched = true; |
849 | // Reset fling state |
850 | mFlingDirection = 0; |
851 | return true; |
852 | } |
853 |
854 | @Override |
855 | public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { |
856 | // int scrollOffset = 0; |
857 | if (e2.getAction() == MotionEvent.ACTION_MOVE) { |
858 |
859 | if (mIsDragging == false) { |
860 | // Stop animation |
861 | mIsTouched = true; |
862 | // Reconfigure scroll |
863 | mIsDragging = true; |
864 | mFlingDirection = 0; |
865 | mScrollTimestamp = System.currentTimeMillis(); |
866 | mCurrentOffset = mViews[mCurrentViewNumber].getCurrentOffset(); |
867 | } |
868 |
869 | float maxVelocity = mGalleryWidth / (mAnimationDuration / 1000.0f); |
870 | long timestampDelta = System.currentTimeMillis() - mScrollTimestamp; |
871 |
872 | if (MoveStyle == MOVE_LEFT_RIGHT) { |
873 | float maxScrollDelta = maxVelocity * (timestampDelta / 1000.0f); |
874 | float currentScrollDelta = e1.getRawX() - e2.getRawX(); |
875 |
876 | if (currentScrollDelta < maxScrollDelta * -1) |
877 | currentScrollDelta = maxScrollDelta * -1; |
878 | if (currentScrollDelta > maxScrollDelta) |
879 | currentScrollDelta = maxScrollDelta; |
880 | int scrollOffset = Math.round(mCurrentOffset[0] + currentScrollDelta); |
881 |
882 | // We can't scroll more than the width of our own |
883 | // framelayout |
884 | if (scrollOffset >= mGalleryWidth) |
885 | scrollOffset = mGalleryWidth; |
886 | if (scrollOffset <= mGalleryWidth * -1) |
887 | scrollOffset = mGalleryWidth * -1; |
888 | mViews[_xViewNumbers.get(0)].setOffset(scrollOffset, 0, mCurrentViewNumber); |
889 | mViews[_xViewNumbers.get(1)].setOffset(scrollOffset, 0, mCurrentViewNumber); |
890 | mViews[_xViewNumbers.get(2)].setOffset(scrollOffset, 0, mCurrentViewNumber); |
891 | // h_viewnumber=mCurrentViewNumber; |
892 | } |
893 |
894 | if (MoveStyle == MOVE_UP_DOWN) { |
895 |
896 | float maxVelocity_Y = mGalleryHeight / (mAnimationDuration / 1000.0f); |
897 | float maxScrollDelta_Y = maxVelocity_Y * (timestampDelta / 1000.0f); |
898 | float currentScrollDelta_Y = e1.getRawY() - e2.getRawY(); |
899 | if (currentScrollDelta_Y < maxScrollDelta_Y * -1) |
900 | currentScrollDelta_Y = maxScrollDelta_Y * -1; |
901 | if (currentScrollDelta_Y > maxScrollDelta_Y) |
902 | currentScrollDelta_Y = maxScrollDelta_Y; |
903 | int scrollOffset_Y = Math.round(mCurrentOffset[1] + currentScrollDelta_Y); |
904 | if (scrollOffset_Y >= mGalleryHeight) |
905 | scrollOffset_Y = mGalleryHeight; |
906 | if (scrollOffset_Y <= mGalleryHeight * -1) |
907 | scrollOffset_Y = mGalleryHeight * -1; |
908 | mViews[_yViewNumbers.get(0)].setOffset(0, scrollOffset_Y, mCurrentViewNumber); |
909 | mViews[_yViewNumbers.get(1)].setOffset(0, scrollOffset_Y, mCurrentViewNumber); |
910 | mViews[_yViewNumbers.get(2)].setOffset(0, scrollOffset_Y, mCurrentViewNumber); |
911 | } |
912 | } |
913 | return false; |
914 | } |
915 |
916 | @Override |
917 | public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { |
918 | if (Math.abs(e1.getY() - e2.getY()) <= swipe_max_off_path) { |
919 | if (e2.getX() - e1.getX() > swipe_min_distance && Math.abs(velocityX) > swipe_threshold_veloicty) { |
920 | // movePrevious_RL(); |
921 | } |
922 | if (e1.getX() - e2.getX() > swipe_min_distance && Math.abs(velocityX) > swipe_threshold_veloicty) { |
923 | // moveNext_RL(); |
924 | } |
925 | if (e2.getY() - e1.getY() > swipe_min_distance && Math.abs(velocityY) > swipe_threshold_veloicty) { |
926 | // movePrevious_UD(); |
927 | } |
928 | if (e1.getY() - e2.getY() > swipe_min_distance && Math.abs(velocityY) > swipe_threshold_veloicty) { |
929 | // moveNext_UD(); |
930 | } |
931 |
932 | } |
933 |
934 | return false; |
935 | } |
936 |
937 | @Override |
938 | public void onLongPress(MotionEvent e) { |
939 | // Finalise scrolling |
940 | mFlingDirection = 0; |
941 | processGesture(); |
942 | } |
943 |
944 | @Override |
945 | public void onShowPress(MotionEvent e) { |
946 | } |
947 |
948 | @Override |
949 | public boolean onSingleTapUp(MotionEvent e) { |
950 | // Reset fling state |
951 | return false; |
952 | } |
953 | } |
954 |
955 | } |
相关资讯 — 更多
|
| 相关文档 — 更多
|
内容信息
0.0
(已有0个人评价)
0%
0%
0%
0%
0%
浏览:171次
贡献者:openkk
上传时间:2012-04-11 19:40:09
经验标签
Android
同类热门经验
- 上百个Android开源项目分享 3860次浏览
- Android 软件自动更新功能的实现 5118次浏览
- 用Android-X86和VirtualBox打造高性能Android开发环境 3068次浏览
- 自定义 Android 对话框 (AlertDialog) 的样式 7023次浏览
- Android实现应用下载并自动安装apk包 1624次浏览
- 在Android中通过XFire WebService远程上传以及下载图片 1010次浏览
相关经验
- android 自定义组件之URLImageView
0人评 - Android 自定义progressDialog实现
0人评 - Android 自定义 ImageView
0人评 - 自定义Android LoadingDialog
0人评 - android自定义控件实例
1人评 - 自定义Android的Spinner
0人评 - Android中Spinner下拉列表(使用ArrayAdapter和自定义Adapter实现) .
1人评 - Android 自定义TabHost风格
0人评 - Android ExpandableListView 样式自定义
1人评 - Android自定义气球Overlay的开发
0人评 - 自定义 Android 对话框 (AlertDialog) 的样式
5人评 - Android 众多的布局属性详解
1人评 - Android ListView元素间隙线自定义渐变效果
0人评 - 利用Android PopupWindow 实现自定义弹出层
0人评
相关讨论 - 更多
- android类库
- Android AIDL 远程服务器使用示例
- Android 简介
- Android 编程基础
- Android 中各种 JAVA 包的功能描述
- Android StrictMode 介绍
- Android核心模块内容概述
联系我们 - 问题反馈
2005-2012 OPEN-OPEN, all rights reserved.
更多相关文章
- Android多媒体--利用Service实现背景音乐的播放
- android 开发论坛资源URL
- android开发环境搭建之我见myeclipse8.5 jdk1.6
- android java开发 第一天 之熟悉eclipse adt
- Android之UI学习篇七:ImageView实现适屏和裁剪图片的功能
- Android(安卓)架构篇----------Framework初识
- Android实现widget定时更新
- as随笔
- 浅谈Java中Collections.sort对List排序的两种方法