使用android ProgressBar和Toast生成一個界面


首先我需要這樣一個界面

這個界面是在使用AudioManager.adjustStreamVolume(int streamType, int direction, int flags)顯示出來的,記住flags這里傳 AudioManager.FLAG_SHOW_UI才會顯示

不然只是邏輯上調整了某個流的聲音,用戶他看不到界面不知道成功與否。

然后我有一個功能界面是和這個一樣的,但功能不一樣,好吧,我知道android自帶的界面並不好看,但這里只是說明原理和方法,美觀不予討論。

這里核心的2個組件就是一個TextView和ProgressBar。如果自定義的話,需要寫一個layout來包裹這2個組件 然后當點擊一個按鈕時顯示出來。

讓我們在回到android自帶的界面中,當他點擊一個按鈕時,他會彈出來並且隔一會就會自動消失。這個自動消失我覺得很有用,因為用戶只需要調整那一會

能看到界面的改變就行了,不需要一直顯示,不然還要讓用戶在點個返回?多么麻煩呢,操作簡單才是重要的。

於是我想到了android 自帶的toast有這個功能。好的!大方向確定了,就開始寫代碼吧

邏輯是這樣的讓用戶點擊某個按鈕時,彈出上面那個界面,然后過一會消失,這里在顯示toast的時候還需要調用改變進度條進度的方法。

接下來上代碼吧:

    // ////////////////////////先生成一個toast和progress界面
pb = new ProgressBar(context, null,

android.R.attr.progressBarStyleHorizontal);
pb.setMax(GameConfig.GameSpeedMax);
pb.setProgress(GameConfig.GameSpeedDefault);
pb.setLayoutParams(new LinearLayout.LayoutParams(
ExtensionLayoutConfig.ProgressBarWidth,
LinearLayout.LayoutParams.WRAP_CONTENT));
toast = Toast.makeText(context,
RFileIDConvert.getString("gameSpeedBarTitle"),
Toast.LENGTH_LONG);
toast.setGravity(Gravity.TOP, 0, 0);
LinearLayout toastView = (LinearLayout) toast.getView();
toastView.setGravity(Gravity.CENTER);
//請注意這里傳1是必要的,因為他的textView已經在創建的時候添加進去了,如果你傳0
//那么上面會先顯示進度條 下面再顯示文字,如果你需要的話可以這么做,但我現在需要
//文字在上方 進度條在下面 so 傳1
toastView.addView(pb, 1);

 

 

下面是給外部調用的2個接口:

    /**
* 設置進度
*/

public void setGameSpeedBarProgress(int progress) {
pb.setProgress(progress);
}
/**
* 顯示toast
*/

public void gameSpeedBarShow() {
toast.show();
}

出來的效果是這樣

發現和原來的相比沒那么大氣,所以還需要調整下間距,這個簡單 我明天再完善它, 大概功能就是這樣了。

總結。大家請不要小看這么一個界面,我剛開始也覺得很容易,可實現起來發現的問題也不少。

1.一般布局我習慣用代碼布局,但碰到ProgressBar我只能無語。在代碼中默認的風格是環形的,在XML布局中默認的是水平的

xml中他默認是這么設置的 <ProgressBar  style="?android:attr/progressBarStyleHorizontal"

呵呵,難點出來了,這個如果你想用代碼設置的話,告訴你很抱歉沒有設置風格的方法。有人會說了ProgressBar  中不是有個setScrollBarStyle(int style)方法么。

那么我請你測試完了在說話。這個方法是無效的,請看API的描述。然后我查源碼想找出水平方向風格使用了那些設置接口,

我們可以看下progressBarStyleHorizontal樣式中給View設置了哪些屬性,我們找到framework下的res目錄下的values/Theme.xml文件,搜索progressBarStyleHorizontal會發現如下行:

 <item name="progressBarStyleHorizontal">@android:style/Widget.ProgressBar.Horizontal</item>

該主題對應的Widget樣式是Widget.ProgressBar.Horizontal,我們在同樣的的目錄下打開style.xml文件,搜索該樣式,可以找到如下代碼:

  <style name="Widget.ProgressBar.Horizontal">

        <item name="android:indeterminateOnly">false</item>

        <item name="android:progressDrawable">@android:drawable/progress_horizontal</item>

        <item name="android:indeterminateDrawable">@android:drawable/progress_indeterminate_horizontal</item>

        <item name="android:minHeight">20dip</item>

        <item name="android:maxHeight">20dip</item>

    </style>

好了,看到這里告訴你,你可以不使用<item name="progressBarStyleHorizontal">@android:style/Widget.ProgressBar.Horizontal</item>

而使用

android:indeterminateOnly="false"

android:progressDrawable="@android:drawable/progress_horizontal"

android:indeterminateDrawable="@android:drawable/progress_indeterminate_horizontal"

android:minHeight="20dip"

android:maxHeight="20dip" />

同樣可以實現水平進度條。我知道大家都會使用那一行而不使用這么多行。我明白,我只是告訴你原理而已。

好的,你知道我喜歡使用代碼布局的,然后走代碼路線則是

progressBar.setIndeterminate(false);

progressBar.setProgressDrawable(getResources().getDrawable(android.R.drawable.progress_horizontal));

progressBar.setIndeterminateDrawable(getResources().getDrawable(android.R.drawable.progress_indeterminate_horizontal));

progressBar.setMinimumHeight(20);

 

結果是ProgressBar確實變成了橫條,但並沒有顯示成進度條的樣子,我們仔細對比一下純Java代碼和xml布局文件之間差異,我們發現

android:indeterminateOnly="false"和 progressBar.setIndeterminate(false);

並不完全一樣布局文件的屬性有一個Only結尾但代碼中並沒有,我們查找Api發現並沒有setIndeterminateOnly這樣的一個方法。

我們打開ProgressBar的源代碼,找到.setIndeterminate(false) 方法。

 

我們這時候可以發現Indeterminate和IndeterminateOnly並不是同一個東西,

這時我們應該想的到,只要我們把IndeterminateOnly的值變成false就可以使ProgressBar變成進度條的樣式,

我們查找所有的代碼,發現並沒有提供相應的公開方法來修改該屬性的值。

 

 

也就是說,我們討論了那么久發現根本就無法通過純代碼的形式來創建一個水平進度條樣式的ProgressBar.

但是。。。某人說可以使用反射改變一個類的私有變量的值。內容比較抽象,這里還是略過吧,因為我發現它必須知道變量名才能反射成功,

但我查詢后發現有些版本的變量名是不一樣的咧,這個版本用的mIndeterminateOnly,那個版本用的mOnlyIndeterminate(2.2版)

所以這個地方我果斷放棄了純代碼布局,使用

ProgressBar pb = new ProgressBar(context, null,android.R.attr.progressBarStyleHorizontal);  安逸了~~~~ 這只是第一個問題哦

2.使用toast的時候需要注意,如果你需要那個背景框就必須makeToast. 如果你喜歡干凈的話 可以使用new Toast(context)然后再設置一些屬性之類的

如果只想要toast的短暫顯示的功能,界面完全自定義的話 推薦使用new Toast(context),最后大家要養成看源碼的習慣哦,有時候還是需要自己動手,

豐衣足食啊

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM