一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Android - Android仿UC瀏覽器左右上下滾動功能

Android仿UC瀏覽器左右上下滾動功能

2021-04-26 18:03林炳文Evankaka Android

這篇文章主要介紹了Android仿UC瀏覽器左右上下滾動功能,左右滑動顯示菜單,上下滑動滾動內容,需要的朋友可以參考下

本文要解決在側滑菜單右邊加個文本框,并能實現文本的上下滑動和菜單的左右滾動。這里推薦可以好好看看android的觸摸事件的分發機制,這里我就不詳細講了,我只講講這個應用。要實現的功能就像uc瀏覽器(或其它手機瀏覽器)的左右滾動,切換網頁,上下滾動,拖動內容。
本文的效果:

Android仿UC瀏覽器左右上下滾動功能

Android仿UC瀏覽器左右上下滾動功能

一、功能要求與實現
1、功能要求:
(1)手指一開始按著屏幕左右移動時,只能左右滾動菜單,如果這時手指一直按著,而且上下移動了,那么菜單顯示部分保持不變,但文本框也不上下移動!                      
(2)手指一開始按著屏幕上下移動時,只能上下滾動文本框,如果這時手指一直按著,而且左右移動了,那么文本框顯示部分保持不變,但菜單也不左右移動!
2、初步實現:
      左邊的菜單項增加一個listview,為右邊的內容項添加一個textview,并且為了能讓它實現上下滾動的功能,給textview加了個scrollview。
       這種效果肯定是不對的,你看,我們手指上下禾移動文本時,如果還左右移動了,菜單也顯示出來了。

 Android仿UC瀏覽器左右上下滾動功能

Android仿UC瀏覽器左右上下滾動功能

3、修改實現   
     這時我就想從觸摸事件的分發入手,這里因為我是把scrollview的觸摸事件注冊到linearlayout。(linearlayout中包含了scrollview,不懂看下面的布局)中去,所以觸摸事件會先傳遞給linearlayout。
分以下兩種情況:
(1)如果是手指左右移動,則把觸摸事件傳給linearlayout。函數ontouch返回true,表示觸摸事件不再傳遞下去,那么scrollview就動不了了
(2)如果是手指上下移動,觸摸事件先傳給linearlayout,但linearlayout不做任何處理,直接傳遞給scrollview,scrollview來處理觸摸事件。
這是修改后的效果:

Android仿UC瀏覽器左右上下滾動功能                                             

二、布局與代碼
1、布局

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<linearlayout xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:tools="http://schemas.android.com/tools"
 android:id="@+id/layout"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:orientation="horizontal"
 tools:context=".mainactivity" >
 <linearlayout
  android:id="@+id/menu"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:orientation="vertical"
  android:background="@drawable/menu" >
  <!-- 添加一個listview控件 -->
   <listview
   android:id="@+id/menulist"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"/>  
 </linearlayout>
  
 <linearlayout
  android:id="@+id/content"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:orientation="vertical">
<scrollview
 android:id="@+id/scrollview"
 android:layout_width="fill_parent"
 android:layout_height="wrap_content" >
  <textview android:id="@+id/content_text"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:text="@string/text1"
    android:textsize="22px" />
 </scrollview>
 </linearlayout>
 
</linearlayout>

2、代碼

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
package com.example.learningjava;
import java.util.arraylist;
import java.util.hashmap;
import java.util.map;
import com.example.learningjava.r.string;
import android.r.integer;
import android.r.menu;
import android.os.asynctask;
import android.os.build;
import android.os.bundle;
import android.annotation.suppresslint;
import android.annotation.targetapi;
import android.widget.adapterview;
import android.widget.adapterview.onitemclicklistener;
import android.widget.arrayadapter;
import android.widget.linearlayout.layoutparams;
import android.widget.listview;
import android.widget.scrollview;
import android.widget.toast;
import android.app.activity;
import android.content.context;
import android.util.attributeset;
import android.util.displaymetrics;
import android.util.log;
import android.view.gesturedetector;
import android.view.menu;
import android.view.motionevent;
import android.view.velocitytracker;
import android.view.view;
import android.view.view.ontouchlistener;
import android.view.window;
import android.widget.linearlayout;
 
public class mainactivity extends activity implements ontouchlistener{
  
 private linearlayout menulayout;//菜單項
 private linearlayout contentlayout;//內容項
 private layoutparams menuparams;//菜單項目的參數
 private layoutparams contentparams;//內容項目的參數contentlayout的寬度值
  
 private int displaywidth;//手機屏幕分辨率
 private float xdown;//手指點下去的橫坐標
 private float xmove;//手指移動的橫坐標
 private float xup;//記錄手指上抬后的橫坐標
 private float ydown;//手指點下去的縱坐標
 private float ymove;//手指移動的縱坐標
  
 private velocitytracker mvelocitytracker; // 用于計算手指滑動的速度。
 private float velocityx;//手指左右移動的速度
 public static final int snap_velocity = 400; //滾動顯示和隱藏menu時,手指滑動需要達到的速度。
 
 private boolean menuisshow = false;//初始化菜單項不可翙
 private static final int menupadding=160;//menu完成顯示,留給content的寬度
  
 private listview menulistview;//菜單列表的內容
 private scrollview scrollview;// 文本框的滾動條
 private boolean wanttoscrolltext=false;//想要下下滾動文本內容
 private boolean wanttoscrolltextmenu=false;
 private boolean onefucction=false;//確保函數只被調用一次
  
 protected void oncreate(bundle savedinstancestate) {
  super.oncreate(savedinstancestate);
  requestwindowfeature(window.feature_no_title);
  setcontentview(r.layout.activity_main);
  initlayoutparams();
  initmenulist();
  initscrollview();
 }
 /**
 *初始化layout并設置其相應的參數
 */
 private void initlayoutparams()
 {
 //得到屏幕的大小
  displaymetrics dm = new displaymetrics();
  getwindowmanager().getdefaultdisplay().getmetrics(dm);
  displaywidth =dm.widthpixels;
  
  //獲得控件
  menulayout = (linearlayout) findviewbyid(r.id.menu);
  contentlayout = (linearlayout) findviewbyid(r.id.content);
  findviewbyid(r.id.layout).setontouchlistener(this);
  
  //獲得控件參數
  menuparams=(linearlayout.layoutparams)menulayout.getlayoutparams();
  contentparams = (linearlayout.layoutparams) contentlayout.getlayoutparams();
  
  //初始化菜單和內容的寬和邊距
  menuparams.width = displaywidth - menupadding;
  menuparams.leftmargin = 0 - menuparams.width;
  contentparams.width = displaywidth;
  contentparams.leftmargin=0;
  
  //設置參數
  menulayout.setlayoutparams(menuparams);
  contentlayout.setlayoutparams(contentparams);
  
 }
 /**
 * 初始化菜單列表內容
 */
 private void initmenulist()
 {
 final string[] strs = new string[] { "第1章 java概述 ", "第2章 理解面向對象", "第3章 數據類型和運算符", "第4章 流程控制和數組", "第5章 面向對象(上)"};
  menulistview = (listview) findviewbyid(r.id.menulist);
  menulistview.setadapter(new arrayadapter<string>(this,android.r.layout.simple_list_item_1, strs));//為listview綁定適配器
  //啟動列表點擊監聽事件
  menulistview.setonitemclicklistener(new onitemclicklistener() {
   @override
   public void onitemclick(adapterview<?> arg0, view arg1, int arg2,long arg3) {
     toast.maketext(getapplicationcontext(),"您選擇了" + strs[arg2], toast.length_short).show();
     
   }
  });
   
 }
 /**
 * 初始化scrollview
 */
 public void initscrollview(){
  scrollview = (scrollview)this.findviewbyid(r.id.scrollview);
  scrollview.setontouchlistener(this);//綁定監聽側滑事件的view,即在綁定的view進行滑動才可以顯示和隱藏左側布局。 這句非常重要,不要設置它的觸摸事件 了,要不會吞掉布局的觸摸事件
 }
 
 @override
 public boolean ontouch(view v, motionevent event)
 {
  acquirevelocitytracker(event);
  if (event.getaction()==motionevent.action_down)
  {
   xdown=event.getrawx();
   ydown=event.getrawy();
   return false;
  }
  else if(event.getaction()==motionevent.action_move)
  {
   if(wanttoscrolltext)//當前想滾動顯示文本
    return false;
   xmove=event.getrawx();
   ymove=event.getrawy();
   if(menuisshow){
    isscrolltoshowmenu();
    return true;
   }
   if(!onefucction)
   {
   onefucction=true;
   //這個if只能被調用一次
   if(math.abs(xdown-xmove)<math.abs(ydown-ymove))
    {
    wanttoscrolltext=true;
    return false;
    }
   
   isscrolltoshowmenu();
  }
  
  else if(event.getaction()==motionevent.action_up) 
  {
   onefucction=false;
   if(wanttoscrolltext){
   wanttoscrolltext=false;
   return false;
   
   xup=event.getrawx();
   isshowmenu();
   releasevelocitytracker();
  }
  
  else if (event.getaction()==motionevent.action_cancel)
  
   releasevelocitytracker();
   return false;
  }
  return true;//false時才能把觸摸事件再傳給scroll
 }
 /**
 * 根據手指按下的距離,判斷是否滾動顯示菜單
 */
 private void isscrolltoshowmenu()
 {
  int distancex = (int) (xmove - xdown); 
  if (!menuisshow) {
   scrolltoshowmenu(distancex);
  }else{
   scrolltohidemenu(distancex);
  }
 }
 /**
 * 手指抬起之后判斷是否要顯示菜單
 */
 private void isshowmenu()
 {
  velocityx =getscrollvelocity();
  if(wanttoshowmenu()){
   if(shouldshowmenu()){
    showmenu();
   }else{
    hidemenu();
   }
  }
  else if(wanttohidemenu()){
   if(shouldhidemenu()){
    hidemenu();
   }else{
    showmenu();
   }
  
 }
 /**
 *想要顯示菜單,當向右移動距離大于0并且菜單不可見
 */
 private boolean wanttoshowmenu(){
  return !menuisshow&&xup-xdown>0;
 }
 /**
 *想要隱藏菜單,當向左移動距離大于0并且菜單可見
 */
 private boolean wanttohidemenu(){
  return menuisshow&&xdown-xup>0;
 }
 /**
 *判斷應該顯示菜單,當向右移動的距離超過菜單的一半或者速度超過給定值
 */
 private boolean shouldshowmenu(){
  return xup-xdown>menuparams.width/2||velocityx>snap_velocity;
 }
 /**
 *判斷應該隱藏菜單,當向左移動的距離超過菜單的一半或者速度超過給定值
 */
 private boolean shouldhidemenu(){
  return xdown-xup>menuparams.width/2||velocityx>snap_velocity;
 }
 /**
 * 顯示菜單欄
 */
 private void showmenu()
 {
  new showmenuasynctask().execute(50);
  menuisshow=true;
 }
 /**
 * 隱藏菜單欄
 */
 private void hidemenu()
 {
  new showmenuasynctask().execute(-50);
  menuisshow=false;
 }
 /**
 *指針按著時,滾動將菜單慢慢顯示出來
 *@param scrollx 每次滾動移動的距離
 */
 private void scrolltoshowmenu(int scrollx)
 {
  if(scrollx>0&&scrollx<= menuparams.width)
  menuparams.leftmargin =-menuparams.width+scrollx;
  menulayout.setlayoutparams(menuparams);
 }
 /**
 *指針按著時,滾動將菜單慢慢隱藏出來
 *@param scrollx 每次滾動移動的距離
 */
 private void scrolltohidemenu(int scrollx)
 {
  if(scrollx>=-menuparams.width&&scrollx<0)
  menuparams.leftmargin=scrollx;
  menulayout.setlayoutparams(menuparams);
 }
  
 
 /**
 * 創建velocitytracker對象,并將觸摸content界面的滑動事件加入到velocitytracker當中。
 * @param event 向velocitytracker添加motionevent
 */
 private void acquirevelocitytracker(final motionevent event) {
  if(null == mvelocitytracker) {
   mvelocitytracker = velocitytracker.obtain();
  }
  mvelocitytracker.addmovement(event);
 }
 /**
 * 獲取手指在content界面滑動的速度。
 * @return 滑動速度,以每秒鐘移動了多少像素值為單位。
 */
 private int getscrollvelocity() {
  mvelocitytracker.computecurrentvelocity(1000);
  int velocity = (int) mvelocitytracker.getxvelocity();
  
  return math.abs(velocity);
 }
 /**
 * 釋放velocitytracker
 */
 private void releasevelocitytracker() {
  if(null != mvelocitytracker) {
   mvelocitytracker.clear();
   mvelocitytracker.recycle();
   mvelocitytracker = null;
  }
 }
 /**
 *
 *:模擬動畫過程,讓肉眼能看到滾動的效果
 *
 */
 class showmenuasynctask extends asynctask<integer, integer, integer>
 {
 
  @override
  protected integer doinbackground(integer... params)
  {
   int leftmargin = menuparams.leftmargin;
   while (true)
   {// 根據傳入的速度來滾動界面,當滾動到達左邊界或右邊界時,跳出循環。
    leftmargin += params[0];
    if (params[0] > 0 && leftmargin > 0)
    {
     leftmargin= 0;
     break;
    } else if (params[0] < 0 && leftmargin <-menuparams.width)
    {
     leftmargin=-menuparams.width;
     break;
    }
    publishprogress(leftmargin);
    try
    {
     thread.sleep(40);//休眠一下,肉眼才能看到滾動效果
    } catch (interruptedexception e)
    {
     e.printstacktrace();
    }
   }
   return leftmargin;
  }
  @override
  protected void onprogressupdate(integer... value)
  {
   menuparams.leftmargin = value[0];
   menulayout.setlayoutparams(menuparams);
  }
 
  @override
  protected void onpostexecute(integer result)
  {
   menuparams.leftmargin = result;
   menulayout.setlayoutparams(menuparams);
  }
 
 }
}

三、原理與說明
原理 :
1、將scrollview的觸摸事件注冊到linearlayout中去。(linearlayout中包含了scrollview,不懂看布局)
2、首先判斷手勢是想要左右運動還是上下運動,如果是左右運動,那么linearlayout得到觸摸事件,即函數ontouch返回true;如果想上下運動,即函數ontouch返回false;
這里要注意的是,手勢判斷只一次,什么意思呢?就是說你第1次按下,到你一直按著,這中間只判斷一次你的手勢想要做的運動。
3、手指離開屏幕后,再來恢復所有的參數。

Android仿UC瀏覽器左右上下滾動功能

這是為大家分享的源碼,請下載:android仿uc瀏覽器左右上下滾動功能,希望本文所述對大家學習android軟件編程有所幫助。

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 边摸边吃奶边做爽gif动态图 | 国产精品成人免费 | 欧美人妖草草xxoo | 精品一区二区三区五区六区 | 亚洲乱亚洲乱妇41p 亚洲乱码一区二区三区国产精品 | 美女被扣逼| 欧美日韩导航 | 国产成人精品高清免费 | 日韩久久影院 | 国产视频二 | 免费在线视频网站 | 非洲黑人xxxxxbbbbb | 四虎最新免费观看网址 | 91久久青青草原线免费 | 欧美精品黑人巨大在线播放 | 婷婷综合缴情亚洲五月伊 | 黑人粗长巨茎小说 | 91天堂国产在线 在线播放 | 日本女人www | 放荡女小洁的性日记 | 99热国产在线观看 | 91精品国产亚一区二区三区 | 日日爱爱 | 精品国产中文字幕在线视频 | 99热这里只有精品一区二区三区 | 無码一区中文字幕少妇熟女网站 | 国产福利一区二区三区 | japanese日本护士 | 国产盗摄女厕美女嘘嘘 | 成人青青草 | 91久久国产成人免费观看资源 | 国产动作大片 | 欧美一级xxxx俄罗斯一级 | 视频免费在线 | 糖心在线观看 | 国产午夜成人无码免费看 | 人妖女天堂视频在线96 | 亚洲国产一区二区a毛片 | 出轨同学会2在线观看 | 羞羞视频免费观看网站 | 深夜在线 |