編輯:關於Android編程
文章伊始,讓我們先靜心回憶三秒:在我們寫過的Android應用當中,是不是有很多地方都離不開數據加載的需求呢?如果是,那麼我們首先來看下圖:
好的,從這裡開始我們暫時忘記自己是一個安卓開發者,而是以一個不懂技術的APP使用者的身份來繼續接下來的交流。
如果是作為一個使用者,那麼現在我們的內心應該是懵逼的。因為自打我們打開這個應用進入到第一個界面後,就發現沒有任何內容。這個時我們可能會開始推測:什麼鬼?手機斷網啦?再一看,網絡正常啊!繼續推測…推測…,最後得出結論:這應用傻x吧,刪掉刪掉…..
好的,現在切換回開發者的身份,來推測分析下答案:那麼原因可能為事實上該界面存放有一個ListView用來顯示從服務器獲取的一些信息。但是,的確很可能因為網絡不順暢,服務器內部異常等一些原因造成請求失敗,沒有數據返回。於是造成了頁面沒有內容顯示的窘境。顯然,作為一個優秀的應用,用戶的體驗肯定是頭等大事。所以很必須的,針對於這種類似的情況,我們應該給用戶一些友好的提示。
那麼,現在我們可以初步的改進一下代碼,比如改進為下面這樣的效果:<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4NCjxwPjxpbWcgYWx0PQ=="這裡寫圖片描述" src="/uploadfile/Collfiles/20160910/20160910092348102.gif" title="\" />
可以看到,現在當我們發現本次請求沒有成功返回數據的時候及時對用戶做了交代,起碼用戶明白這次沒有獲取到“數據”。這就比之前友好一些了。
不得不說這其實是很一種很常見,但是也很有必要的做法。而且要實現這種需求也相當簡單,為listview進行setEmptyView就可以了。
這種東西已經不是新鮮事了。以上布局文件中,id為empty的部分就是我們想要在沒有獲取到的數據的時候提供給用戶看的view。
隨後的做法也很簡單,在Java代碼中調用setEmptyView把指定的view設置給ListView就可以了。
這種布局簡單且具有代表性,與我們平常寫的沒有任何不同。然後來看下怎麼通過SmartLoadingLayout來為這個界面加上不同的切換狀態。
public class MainActivity extends AppCompatActivity { private TextView tvContent; private DefaultLoadingLayout mLayout; //SmartLoadingLayout對象 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); tvContent = (TextView) findViewById(R.id.tv_content); mLayout = SmartLoadingLayout.createDefaultLayout(this, tvContent); } }
以上所有的代碼相信我們都很熟悉,唯一的額外工作是需要一個DefaultLoadingLayout對象。
DefaultLoadingLayout通過調用SmartLoadingLayout的靜態方法createDefaultLayout就可以成功獲取。
該方法需要兩個參數,一個是界面的宿主Activity,另一個就是傳入我們選擇作為內容的view(比如這裡就是TextView)。
OK,到了這裡,我們的一切准備工作就已經完成了,就是這麼的簡單。那麼,通過以下的代碼邏輯我們就可以模擬出等待數據加載並顯示的效果:
private Handler mHandler = new Handler(){ @Override public void handleMessage(Message msg) { // 數據下載完成,轉換狀態,顯示內容視圖 mLayout.onDone(); } }; @Override protected void onCreate(Bundle savedInstanceState) { //...... //進入loading狀態 mLayout.onLoading(); new Thread(new Runnable() { @Override public void run() { // 這裡是模擬下載數據的耗時過程 downloadData(); // 數據下載完畢後,通知handler mHandler.sendEmptyMessage(1); } }).start(); }
然後讓我們運行程序看一下效果:
看上去是不是還不錯呢?可以看到我們需要做的就是在開始加載數據的時候調用onLoading方法,然後在成功獲取數據後調用onDone方法就搞定了。
那麼,現在假設這次我們進入時沒有獲取到數據,也就是我們之前說的空視圖。那麼,也很簡單,將之前代碼的onDone改為onEmpty就可以了。
private Handler mHandler = new Handler(){ @Override public void handleMessage(Message msg) { mLayout.onEmpty(); } };
讓我們再次運行程序看看效果:
現在我們就輕車熟路了。同理,如果是讀取數據的過程中發生了網絡異常呢?我們再把onEmpty改為onError。然後再看看效果:
再接著看,可以看到就像上一張圖中演示的一樣,error狀態下通常會有一個按鈕,來執行某種操作,通常來說是用於再次發送請求刷新界面的。
那麼,我們應該怎麼樣為這個按鈕添加這個操作呢?別急。大家可能還會有其它問題,比如:
我覺得這個錯誤界面的圖形太丑了,我不喜歡;或者我想自己定義錯誤的描述信息;或者按鈕什麼鬼?同樣也不是我想要的等等等等..
沒關系,結合以上問題一起,我們用如下的代碼能夠一次體現所有的解決方式:
mLayout.setErrorButtonListener(new View.OnClickListener() { @Override public void onClick(View v) { mLayout.replaceErrorIcon(R.mipmap.ic_launcher); mLayout.setErrorDescription("This my error information."); mLayout.setErrorDescriptionColor(Color.BLUE); mLayout.setErrorDescriptionTextSize(20); mLayout.setErrorButtonText("oh!no!"); mLayout.setErrorButtonTextColor(Color.RED); mLayout.setErrorButtonBackground(R.drawable.bg_error); } });
同樣的,我們再次運行程序來看看效果:
同理的,如果你不喜歡Loading的效果,不喜歡Empty界面的效果,都可以通過對應的方法來定制為自己喜歡的風格。
但問題又來了,你說了:到目前為止所有的一切我都不太喜歡怎麼辦。那麼我就很尴尬了.
不過也沒關系。還有另一個類型叫做CustomLoadingLayout,通過它所有的界面都可以完全由你自己定制。
比如說,現在我們在自己的項目裡分別定義好了數據加載時各種不同狀態的布局文件。那麼,接下來就把它include進來就行了:
接著是代碼控制:
private CustomLoadingLayout mLayout; //SmartLoadingLayout對象 //............... mLayout = SmartLoadingLayout.createCustomLayout(this); mLayout.setLoadingView(R.id.my_loading_page); mLayout.setContentView(R.id.lv_content); mLayout.setEmptyView(R.id.my_empty_page); mLayout.setErrorView(R.id.my_error_page);
這樣就完成了准備工作,接下來的工作就仍然是在需要的時候調用onLoading此類的方法了。好啦,就寫到這裡吧!
一.兄弟Layout_height為fill_parent本來准備編寫一款簡單的計算器,來學習android,遇到了多個兄弟Layout區域按照一個比例大小來顯示的技術問
在Android開發當中,經常需要用到定位功能,尤其是依賴於地理位置功能的應用,很多人喜歡使用百度地圖,高德地圖提供的sdk,開放API,但是在僅僅需要經緯度,或者城市,
也是今天用到的一個東西,就是簡單實現九宮格的Demo1.就是定義各種layout 和對應的item 我的:<?xml version=1.0 encodin
最近心情比較浮躁,項目初步已經完成一直沒有心情來更新博客,基本功能已經實現了包括添加城市,刪除城市,獲取城市部分天氣預報信息,已經詳細的天氣預報信息,還集成了ShareS