為了提高工作效率,對一些常見View的特殊用法作一下總結。
一、進度條對話框
????? ?坑:https://blog.csdn.net/nailsoul/article/details/38870827?(ProgressBar占據位置但是不顯示的問題)
????????最近我的同事孫大姐提個需求:將進度顯示框的進度條放到文字上方。
????? ?1.使用系統的ProgressDialog
??????????https://www.cnblogs.com/guop/p/5139937.html? (圓形進度條與水平進度條) (注意構造方法要傳theme,否則有些手機可能看不到進度條。)
??????????看不到進度條的還有一種情況就是沒有指定ProgressBar的一個屬性:
?????
??????????
? ?
????????? 注意創建ProgressDialog時不要使用Builder來創建,即:
?????new?ProgressDialog.Builder(mContext).create();
????????? 用這種方式創建的ProgressDialog會不顯示進度條,只會顯示純文字。
? ? ? ? ? 原生的進度顯示框設置樣式為SPINNER,默認進度條放在文字左方,所以無法滿足孫大姐的需求。
???????
????????2.使用AlertDialog自定義View
????????? ?正確的用法:
?????progressDialog?=?new?AlertDialog.Builder(mContext).create(); ?????View?rootView?=?LayoutInflater.from(mContext).inflate(R.layout.mprogress_dialog,?null); ?????pbBar?=?rootView.findViewById(R.id.pb_bar); ?????tvMsg?=?(TextView)?rootView.findViewById(R.id.tvMsg); ?????progressDialog.setView(rootView);
???????????注意錯誤的用法:
?????new?ProgressDialog.Builder(mContext,ProgressDialog.THEME_DEVICE_DEFAULT_DARK).create();
????????? 上面的ProgressDialog.Builder實際上還是父類AlertDialog的類,create出來的是AlertDialog,并非ProgressDialog,無法將AlertDialog強制轉換成ProgressDialog。
????????? ?也就無法使用ProgressDialog的特有方法progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER),因此,如果想通過Builder類創建的dialog來實現圓形進度條對話框,
????????? ?只有自定義view。
???????? 3.繼承的方式
? ? ? ? ? ? 方式1:直接繼承ProgressDialog
????????????研究ProgressDialog的源碼可以發現其onCreate方法里:
??????else{
????????????View?view?=?inflater.inflate(a.getResourceId(
????????????????????com.android.internal.R.styleable.AlertDialog_progressLayout,
????????????????????R.layout.progress_dialog),?null);
????????????mProgress?=?(ProgressBar)?view.findViewById(R.id.progress);
????????????mMessageView?=?(TextView)?view.findViewById(R.id.message);
????????????setView(view);
??????}????????????注意上面的R是com.android.internal.R,如果將布局引用為自己應用的app不就行了。于是繼承ProgressDialog準備復寫onCreate方法:
????????????
????????????可以發現會報各種引用不到的問題,因為這些變量都是父類定義的private變量。
????????????對于變量mContext有public訪問方法
????????????
????????????對于其他沒有public訪問方法的private變量,該如何獲取呢?
????????????答案:反射? ?(代碼附于文章最后)
????????????
? ? ? ? ? ? 還有一項就是系統資源文件com.android.internal.R如何獲取呢?
????????????答案:反射? ?(代碼附于文章最后)
????????????com.android.internal.R是無法在java文件里import的
????????????
????????????將私有變量和方法用反射代替之后,代碼如下:
@Override
protected?void?onCreate(Bundle?savedInstanceState)?{
????????LayoutInflater?inflater?=?LayoutInflater.from(getContext());
????????TypedArray?a?=?getContext().obtainStyledAttributes(null,
????????????????SystemResourceManager.getResourceStyleableIds("AlertDialog"),
????????????????SystemResourceManager.getResourceAttrId("alertDialogStyle")
????????????????,?0);
????????if?((int)ReflectManger.getField(ProgressDialog.class,this,"mProgressStyle")??==?STYLE_HORIZONTAL)?{
????????/*?Use?a?separate?handler?to?update?the?text?views?as?they
?????????*?must?be?updated?on?the?same?thread?that?created?them.
?????????*/
????????????ReflectManger.setField(ProgressDialog.class,this,"mViewUpdateHandler",new?Handler()?{
????????????????@Override
????????????????public?void?handleMessage(Message?msg)?{
????????????????????super.handleMessage(msg);
????????????????/*?Update?the?number?and?percent?*/
????????????????????int?progress?=?((ProgressBar)(ReflectManger.getField(ProgressDialog.class,this,"mProgress"))).getProgress();
????????????????????int?max?=?((ProgressBar)(ReflectManger.getField(ProgressDialog.class,this,"mProgress"))).getMax();
????????????????????if?(ReflectManger.getField(ProgressDialog.class,this,"mProgressNumberFormat")?!=?null)?{
????????????????????????String?format?=?(String)?ReflectManger.getField(ProgressDialog.class,this,"mProgressNumberFormat");
????????????????????????((TextView)ReflectManger.getField(ProgressDialog.class,this,"mProgressNumber")).setText(String.format(format,?progress,?max));
????????????????????}?else?{
????????????????????????((TextView)ReflectManger.getField(ProgressDialog.class,this,"mProgressNumber")).setText("");
????????????????????}
????????????????????if?(ReflectManger.getField(ProgressDialog.class,this,"mProgressPercentFormat")?!=?null)?{
????????????????????????double?percent?=?(double)?progress?/?(double)?max;
????????????????????????SpannableString?tmp?=?new?SpannableString(((NumberFormat)ReflectManger.getField(ProgressDialog.class,this,"mProgressPercentFormat")).format(percent));
????????????????????????tmp.setSpan(new?StyleSpan(android.graphics.Typeface.BOLD),
????????????????????????????????0,?tmp.length(),?Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
????????????????????????((TextView)ReflectManger.getField(ProgressDialog.class,this,"mProgressPercent")).setText(tmp);
????????????????????}?else?{
????????????????????????((TextView)ReflectManger.getField(ProgressDialog.class,this,"mProgressPercent")).setText("");
????????????????????}
????????????????}
????????????});
????????????View?view?=?inflater.inflate(a.getResourceId(
????????????????????SystemResourceManager.getResourceStyleableId("AlertDialog_horizontalProgressLayout"),
????????????????????SystemResourceManager.getResourceLayoutId("alert_dialog_progress")),?null);
????????????ReflectManger.setField(ProgressDialog.class,this,"mProgress",
?????????????????????view.findViewById(SystemResourceManager.getResourceId("progress"))
????????????????????);
????????????ReflectManger.setField(ProgressDialog.class,this,"mProgressNumber",
???????????????????view.findViewById(SystemResourceManager.getResourceId("progress_number"))
????????????);
????????????ReflectManger.setField(ProgressDialog.class,this,"mProgressPercent",
???????????????????view.findViewById(SystemResourceManager.getResourceId("progress_percent"))
????????????);
????????????setView(view);
????????}?else?{
????????????View?view?=?inflater.inflate(a.getResourceId(
????????????????????SystemResourceManager.getResourceStyleableId("AlertDialog_progressLayout"),
????????????????????R.layout.m_progress_dialog),?null);
????????????//注意布局中id的引用:android:id="@android:id/progress"
????????????ReflectManger.setField(ProgressDialog.class,this,"mProgress",
?????????????????????view.findViewById(android.R.id.progress)
????????????);
????????????ReflectManger.setField(ProgressDialog.class,this,"mMessageView",
?????????????????????view.findViewById(R.id.message)
????????????);
????????????setView(view);
????????}
????????a.recycle();
????????if?((int)ReflectManger.getField(ProgressDialog.class,this,"mMax")?>?0)?{
????????????setMax((int)ReflectManger.getField(ProgressDialog.class,this,"mMax")?);
????????}
????????if?((int)ReflectManger.getField(ProgressDialog.class,this,"mProgressVal")?>?0)?{
????????????setProgress((int)ReflectManger.getField(ProgressDialog.class,this,"mProgressVal")?);
????????}
????????if?((int)ReflectManger.getField(ProgressDialog.class,this,"mSecondaryProgressVal")?>?0)?{
????????????setSecondaryProgress((int)ReflectManger.getField(ProgressDialog.class,this,"mSecondaryProgressVal")?);
????????}
????????if?((int)ReflectManger.getField(ProgressDialog.class,this,"mIncrementBy")?>?0)?{
????????????incrementProgressBy((int)ReflectManger.getField(ProgressDialog.class,this,"mIncrementBy")?);
????????}
????if?((int)ReflectManger.getField(ProgressDialog.class,this,"mIncrementSecondaryBy")?>?0)?{
????????incrementSecondaryProgressBy((int)ReflectManger.getField(ProgressDialog.class,this,"mIncrementSecondaryBy")?);
????}
????if?(?ReflectManger.getField(ProgressDialog.class,this,"mProgressDrawable")?!=?null)?{
????????setProgressDrawable((Drawable)?ReflectManger.getField(ProgressDialog.class,this,"mProgressDrawable"));
????}
????if?(?ReflectManger.getField(ProgressDialog.class,this,"mIndeterminateDrawable")?!=?null)?{
????????setIndeterminateDrawable((Drawable)?ReflectManger.getField(ProgressDialog.class,this,"mIndeterminateDrawable"));
????}
????if?(?ReflectManger.getField(ProgressDialog.class,this,"mMessage")?!=?null)?{
????????setMessage((CharSequence)?ReflectManger.getField(ProgressDialog.class,this,"mMessage"));
????}
????setIndeterminate((Boolean)?ReflectManger.getField(ProgressDialog.class,this,"mIndeterminate"));
????try?{
????????ReflectManger.invokeMethod(ProgressDialog.class,this,"onProgressChanged",null,null);
????}?catch?(NoSuchMethodException?e)?{
????????e.printStackTrace();
????}?catch?(InvocationTargetException?e)?{
????????e.printStackTrace();
????}?catch?(IllegalAccessException?e)?{
????????e.printStackTrace();
????}
????super.onCreate(savedInstanceState);
}?????????自定義布局m_progress_dialog.xml??如下:
????<FrameLayout?xmlns:android="http://schemas.android.com/apk/res/android" ????????android:layout_width="match_parent" ????????android:layout_height="wrap_content"> ???? ????????<LinearLayout?android:id="@+id/body" ????????????android:orientation="horizontal" ????????????android:layout_width="match_parent" ????????????android:layout_height="match_parent" ????????????android:baselineAligned="false" ????????????android:paddingStart="8dip" ????????????android:paddingTop="10dip" ????????????android:paddingEnd="8dip" ????????????android:paddingBottom="10dip"> ???? ????????????<ProgressBar?android:id="@android:id/progress" ???????????????? ????????????????android:layout_width="wrap_content" ????????????????android:layout_height="wrap_content" ????????????????android:max="10000" ????????????????android:layout_marginEnd="12dip"?/> ???? ????????????<TextView?android:id="@+id/message" ????????????????android:layout_width="match_parent" ????????????????android:layout_height="wrap_content" ????????????????android:layout_gravity="center_vertical"?/> ????????</LinearLayout> ?????</FrameLayout>
??????????但是復寫的onCreate方法中有個問題
?????????view.findViewById(R.id.message)
??? ? ? ? ?結果返回null,但是這個id明明是存在的。但是view.findViewById(android.R.id.progress)怎么不是null呢?
????????? ?思考半天,看下面的代碼:
? ?????????
??View?view?=?inflater.inflate(a.getResourceId(
????????????????????SystemResourceManager.getResourceStyleableId("AlertDialog_progressLayout"),
????????????????????R.layout.m_progress_dialog),?null);????????? ?R.layout.m_progress_dialog只是一個備用布局,跟本就沒有加載進去。
????????? ?將上面的代碼稍作修改,將getResourceId方法的第一個值傳入一個非法參數0(-1試了不行),這樣R.layout.m_progress_dialog就加載了,果然一切正常。
View?view?=?inflater.inflate(a.getResourceId(
//????????????????????????SystemResourceManager.getResourceStyleableId("AlertDialog_progressLayout"),
????????????????????????0,
????????????????????????R.layout.m_progress_dialog),?null);? ? ? ? ? ?但是圓形進度條不會顯示,上面已經說到了,構造方法要傳theme,但是傳了theme之后,上面代碼又會報下面的錯:
????????????android.content.res.Resources$NotFoundException: File res/drawable-xhdpi-v4/dialog_full_holo_light.9.png from xml type layout resource ID #0x1080295
? ? ? ? ? ? 通過debug發現,如果Dialog構造方法加了主題,resId !=?R.layout.m_progress_dialog
????????????
????????????如果Dialog構造方法不加主題?,
一-2、SeekBar
?自定義樣式
https://blog.csdn.net/u010029983/article/details/45222257? ?(推薦)
https://blog.csdn.net/qq_38407076/article/details/83012684
改變游標圖片大?。篽ttps://www.cnblogs.com/welhzh/p/3711694.html
????????????
二、快速創建一個輸入框
??Builder?builder?=?new?Builder(); ????builder.setTitle(title) ????????????.setMessage(message); ????final?EditText?et?=?new?EditText(builder.getContext()); ????et.setInputType(InputType.TYPE_CLASS_TEXT?|?InputType.TYPE_TEXT_VARIATION_PASSWORD); ????builder.setView(et);
?????? 注意動態設置edittext的inputType為密碼輸入框為:
????InputType.TYPE_CLASS_TEXT?|?InputType.TYPE_TEXT_VARIATION_PASSWORD
?
三、Spinner
?快速創建spinner
private?void?initAreaSpinner(Spinner?spinner_area)?{
????ArrayAdapter<CharSequence>?adapter;
????adapter?=?ArrayAdapter.createFromResource(this,?R.array.area,?android.R.layout.simple_spinner_item);
????spinner_area.setAdapter(adapter);
????spinner_area.setOnItemSelectedListener(new?AdapterView.OnItemSelectedListener()?{
????????@Override
????????public?void?onItemSelected(AdapterView<?>?parent,?View?view,?int?position,?long?id)?{
????????????switch?(position){
????????????????case?0:
????????????????????sdk.setBleAreaType(BleAreaType.HENAN);
????????????????????break;
????????????????case?1:
????????????????????sdk.setBleAreaType(BleAreaType.GUIZHOU);
????????????????????break;
????????????????case?2:
????????????????????sdk.setBleAreaType(BleAreaType.GUANGXI);
????????????????????break;
????????????}
????????}
????????@Override
????????public?void?onNothingSelected(AdapterView<?>?parent)?{
????????}
????});
????spinner_area.setSelection(0);
}? ?? ?
四、PopWindow
????? ?https://github.com/pinguo-zhouwei/CustomPopwindow?(超級方便好用的popwindow)
????????
五、NavigationView
????????1.修改NavigationView中的Item的Icon大小
????????????https://blog.csdn.net/zuolovefu/article/details/50175245
????????2.Android NavigationView 中 menu item 字體大小設置
????????????https://blog.csdn.net/TLD_DLT/article/details/79865525
六、TabLayout
???????? 1.修改字體大小
????????????https://blog.csdn.net/qq_33919497/article/details/78548198
???????? 2.
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。