編輯:關於Android編程
一,為什麼說是真正的高仿?
闡述這個問題前,先說下之前網上的,各位可以復制這段字,去百度一下 "仿微信打開網頁的進度條效果" ,你會看到有很多類似的文章,不過他們有個共同點,就是實現方法都是一樣的,而且,都忽略了微信加載網頁時,進度條的緩慢動畫效果,它不是生硬地一滑而過,而是用戶體驗很好,有個速度的變化,由慢到快的效果,語言難於描述,相信各位都有下載微信,可以隨便打開個公眾號的文章看看效果。
好了,上面說到,之前網上的方法都是都忽略了微信加載網頁時,進度條的緩慢動畫效果,實現代碼也是千篇一律,如下:
/** 先實例化個進度條 */ ProgressBar mProgressBar = (ProgressBar) findViewById(R.id.ProgressBar); /** 再實例化個 webView */ WebView webView = (WebView) findViewById(R.id.webview); /** 然後就直接在 webClient 回調函數裡面set 進度,這樣的做法是生硬的效果 */ webView.setWebChromeClient(new WebChromeClient(){ @Override public void onProgressChanged(WebView view, int newProgress) { super.onProgressChanged(view, newProgress); mProgressBar.setProgress(newProgress); } }); /** 其他是顏色樣式等,不是重點 */ .....
我以為是 ProgressBar 控件可能自身提供了動畫的 API,可惜,沒有,故自己動手寫了這個,你如果找到了,告訴下我。
二,為什麼要搞緩慢效果?
對,為什麼要這麼麻煩,你如果要搞個網頁加載進度條,上面的代碼不過 10 行,妥妥地實現了。因為用戶體驗,我不是產品經理,我是個程序員,而且這個效果也不是有誰叫我這樣去做的,我就是看著別扭,微信的成功,我相信不僅僅是個朋友圈那麼簡單!
程序員應該具備注重用戶體驗的想法。
三,我的實現思路
方法很多,這話我說在前面,我的這種肯定不是最好的,但不失一用或改進。
主要是通過改變 view 的 LayoutParam 來實現有不同速度的移動效果,在每一次的進度段,例如第一次0~24,第二次24~56,這就是兩個進度段,這兩個進度段,具有不同的速度,這個需要計算出來,先根據手機屏幕寬度和 0~100 的進度數值來等比計算出實際的寬度,再計算出移動的速度,計算出來每個進度段的數據後,講它們放進一個列表容器裡面,然後通過一個 handler 來循環提取同期數據,不斷地發消息,不停地 setLayoutParam。在達到 100 後,就證明加載完畢。
在這個過程需要處理計算的誤差,例如第一個加載 20,第二次24,24-20 = 4,4/100,程序裡面是 0 ,如果計算速度的話,就會差生0,所以要稍微加個 if 判斷。
四,代碼,內涵注釋
核心類:
package com.slowlyprogressbar; import android.os.Handler; import android.os.Message; import android.util.Log; import android.view.View; import android.widget.RelativeLayout; import java.util.ArrayList; import java.util.List; /** * Created by 林冠宏 on 2016/7/11. * * 真正的仿微信網頁打開的進度條 * * 下面的所有屬性都可以自己采用 get set 來自定義 * */ public class SlowlyProgressBar { private static final int StartAnimation = 0x12; private Handler handler; private View view; /** 當前的位移距離和速度 */ private int thisWidth = 0; private int thisSpeed = 0; private int progress = 0; /** 當前的進度長度 */ private int record = 0; /** 移動單位 */ private int width = 10; /** 10dp each time */ private int height = 3; /** 3dp */ private boolean isStart = false; private int phoneWidth = 0; /** 屏幕寬度 */ private int i = 0; /** 每次的移動記錄容器,位移對應每幀時間 */ private List<Integer> progressQuery = new ArrayList<>(); private List<Integer> speedQuery = new ArrayList<>(); public SlowlyProgressBar(View view, int phoneWidth) { initHandler(); this.phoneWidth = phoneWidth; this.view = view; } /** 善後工作,釋放引用的持有,方能 gc 生效 */ public void destroy(){ if(progressQuery!=null){ progressQuery.clear(); progressQuery = null; } if(speedQuery!=null){ speedQuery.clear(); speedQuery = null; } view = null; handler.removeCallbacksAndMessages(null); handler = null; } public void setProgress(int progress){ if(progress>100 || progress <= 0){ /** 不能超過100 */ return; } /** 每次傳入的 width 應該是包含之前的數值,所以下面要減去 */ /** 下面記得轉化比例,公式 (屏幕寬度 * progress / 100) */ this.width = (progress * phoneWidth)/100; /** lp.width 總是獲取前一次的 大小 */ /** 移動 100px 時的速度一次倍率 是 2 */ int size = progressQuery.size(); if(size != 0){ size = progressQuery.get(size-1); } Log.d("zzzzz","width - size = "+(width - size)); /** 計算倍率,2/100 = x/width */ int distance = width - size; int speedTime; if(distance<=100){ speedTime = 2; }else{ speedTime = (int) ((2 * distance)/100.0); } /** 添加 */ progressQuery.add(this.width); speedQuery.add(speedTime); /** 開始 */ if(!isStart){ isStart = true; handler.sendEmptyMessage(StartAnimation); } } public SlowlyProgressBar setViewHeight(int height){ this.height = height; return this; } private void initHandler(){ handler = new Handler(){ @Override public void handleMessage(Message msg) { super.handleMessage(msg); switch (msg.what){ case StartAnimation: /** 提取隊列信息 */ if(progress >= thisWidth){ /** 如果已經跑完,那麼移出 */ if(progressQuery.size() == i){ Log.d("zzzzz","break"); if(progress >= 100){ /** 全部走完,隱藏進度條 */ view.setVisibility(View.INVISIBLE); } isStart = false; break; } Log.d("zzzzz", "size is " + progressQuery.size()); thisWidth = progressQuery.get(i); thisSpeed = speedQuery.get(i); i ++; } move(thisSpeed,view.getLayoutParams().width); Log.d("zzzzz", "send 100 "+thisSpeed); /** 發信息的延時長度並不會影響速度 */ handler.sendEmptyMessageDelayed(StartAnimation,1); break; } } }; } /** 移動 */ private void move(int speedTime,int lastWidth){ if(speedTime > 9){ speedTime = 9; /** 控制最大倍率 */ } /** 乘 3 是糾正誤差 */ progress = (record * speedTime); /** 糾正 */ if(progress >= lastWidth){ view.setLayoutParams(new RelativeLayout.LayoutParams(progress,height*3)); }else{ Log.d("zzzzz","hit "+progress+"---"+lastWidth); } record ++; } }
五,使用方法與截圖
超簡單引入,view 可以是隨便一個,例如 TextView,給它一個 background 就行了,就有顏色了。
public class MainActivity extends AppCompatActivity { private SlowlyProgressBar slowlyProgressBar; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); slowlyProgressBar = new SlowlyProgressBar ( findViewById(R.id.p), getWindowManager().getDefaultDisplay().getWidth() ) .setViewHeight(3); WebView webView = (WebView) findViewById(R.id.webview); webView.setWebChromeClient(new WebChromeClient(){ @Override public void onProgressChanged(WebView view, int newProgress) { super.onProgressChanged(view, newProgress); slowlyProgressBar.setProgress(newProgress); } }); webView.loadUrl("http://www.cnblogs.com/linguanh"); } @Override public void finish() { super.finish(); if(slowlyProgressBar!=null){ slowlyProgressBar.destroy(); slowlyProgressBar = null; } } }
以上所述是小編給大家介紹的Android開發之模仿微信打開網頁的進度條效果(高仿),如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對本站網站的支持!
准備需要下載ntfs-3g驅動包,並做相應修改,這個網上已經可以下載到修改好的包,本文最後也會附加。為什麼要移植在Android原生代碼中,只支持了FAT格式的掛載,並未
Case 標簽中的常量字段 在正常的 Android 項目中,資源R類裡的常量是這樣聲明的: public static final int main=0x
在Android Studio上將項目導入Github上: Enable Version Control Integration... 2.選擇Git,點擊
大家好,今天給大家詳解一下Android中Activity的生命周期,我在前面也曾經講過這方面的內容,但是像網上大多數文章一樣,基本都是翻譯Android API,過於籠