您好,登錄后才能下訂單哦!
為了提高工作效率,對(duì)一些常見View的特殊用法作一下總結(jié)。
一、進(jìn)度條對(duì)話框
????? ?坑:https://blog.csdn.net/nailsoul/article/details/38870827?(ProgressBar占據(jù)位置但是不顯示的問題)
????????最近我的同事孫大姐提個(gè)需求:將進(jìn)度顯示框的進(jìn)度條放到文字上方。
????? ?1.使用系統(tǒng)的ProgressDialog
??????????https://www.cnblogs.com/guop/p/5139937.html? (圓形進(jìn)度條與水平進(jìn)度條) (注意構(gòu)造方法要傳theme,否則有些手機(jī)可能看不到進(jìn)度條。)
??????????看不到進(jìn)度條的還有一種情況就是沒有指定ProgressBar的一個(gè)屬性:
?????
??????????
? ?
????????? 注意創(chuàng)建ProgressDialog時(shí)不要使用Builder來創(chuàng)建,即:
?????new?ProgressDialog.Builder(mContext).create();
????????? 用這種方式創(chuàng)建的ProgressDialog會(huì)不顯示進(jìn)度條,只會(huì)顯示純文字。
? ? ? ? ? 原生的進(jìn)度顯示框設(shè)置樣式為SPINNER,默認(rèn)進(jìn)度條放在文字左方,所以無法滿足孫大姐的需求。
???????
????????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);
???????????注意錯(cuò)誤的用法:
?????new?ProgressDialog.Builder(mContext,ProgressDialog.THEME_DEVICE_DEFAULT_DARK).create();
????????? 上面的ProgressDialog.Builder實(shí)際上還是父類AlertDialog的類,create出來的是AlertDialog,并非ProgressDialog,無法將AlertDialog強(qiáng)制轉(zhuǎn)換成ProgressDialog。
????????? ?也就無法使用ProgressDialog的特有方法progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER),因此,如果想通過Builder類創(chuàng)建的dialog來實(shí)現(xiàn)圓形進(jìn)度條對(duì)話框,
????????? ?只有自定義view。
???????? 3.繼承的方式
? ? ? ? ? ? 方式1:直接繼承ProgressDialog
????????????研究ProgressDialog的源碼可以發(fā)現(xiàn)其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,如果將布局引用為自己應(yīng)用的app不就行了。于是繼承ProgressDialog準(zhǔn)備復(fù)寫onCreate方法:
????????????
????????????可以發(fā)現(xiàn)會(huì)報(bào)各種引用不到的問題,因?yàn)檫@些變量都是父類定義的private變量。
????????????對(duì)于變量mContext有public訪問方法
????????????
????????????對(duì)于其他沒有public訪問方法的private變量,該如何獲取呢?
????????????答案:反射? ?(代碼附于文章最后)
????????????
? ? ? ? ? ? 還有一項(xiàng)就是系統(tǒng)資源文件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>
??????????但是復(fù)寫的onCreate方法中有個(gè)問題
?????????view.findViewById(R.id.message)
??? ? ? ? ?結(jié)果返回null,但是這個(gè)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只是一個(gè)備用布局,跟本就沒有加載進(jìn)去。
????????? ?將上面的代碼稍作修改,將getResourceId方法的第一個(gè)值傳入一個(gè)非法參數(shù)0(-1試了不行),這樣R.layout.m_progress_dialog就加載了,果然一切正常。
View?view?=?inflater.inflate(a.getResourceId( //????????????????????????SystemResourceManager.getResourceStyleableId("AlertDialog_progressLayout"), ????????????????????????0, ????????????????????????R.layout.m_progress_dialog),?null);
? ? ? ? ? ?但是圓形進(jìn)度條不會(huì)顯示,上面已經(jīng)說到了,構(gòu)造方法要傳theme,但是傳了theme之后,上面代碼又會(huì)報(bào)下面的錯(cuò):
????????????android.content.res.Resources$NotFoundException: File res/drawable-xhdpi-v4/dialog_full_holo_light.9.png from xml type layout resource ID #0x1080295
? ? ? ? ? ? 通過debug發(fā)現(xiàn),如果Dialog構(gòu)造方法加了主題,resId !=?R.layout.m_progress_dialog
????????????
????????????如果Dialog構(gòu)造方法不加主題?,
一-2、SeekBar
?自定義樣式
https://blog.csdn.net/u010029983/article/details/45222257? ?(推薦)
https://blog.csdn.net/qq_38407076/article/details/83012684
改變游標(biāo)圖片大?。篽ttps://www.cnblogs.com/welhzh/p/3711694.html
????????????
二、快速創(chuàng)建一個(gè)輸入框
??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);
?????? 注意動(dòng)態(tài)設(shè)置edittext的inputType為密碼輸入框?yàn)椋?/p>
????InputType.TYPE_CLASS_TEXT?|?InputType.TYPE_TEXT_VARIATION_PASSWORD
?
三、Spinner
?快速創(chuàng)建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?(超級(jí)方便好用的popwindow)
????????
五、NavigationView
????????1.修改NavigationView中的Item的Icon大小
????????????https://blog.csdn.net/zuolovefu/article/details/50175245
????????2.Android NavigationView 中 menu item 字體大小設(shè)置
????????????https://blog.csdn.net/TLD_DLT/article/details/79865525
六、TabLayout
???????? 1.修改字體大小
????????????https://blog.csdn.net/qq_33919497/article/details/78548198
???????? 2.
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。