android 对话框的父view是谁,Android基础View回顾

为了提高工作效率,对一些常见View的特殊用法作一下总结。

一、进度条对话框

最近我的同事孙大姐提个需求:将进度显示框的进度条放到文字上方。

1.使用系统的ProgressDialog

https://www.cnblogs.com/guop/p/5139937.html  (圆形进度条与水平进度条) (注意构造方法要传theme,否则有些手机可能看不到进度条。)

看不到进度条的还有一种情况就是没有指定ProgressBar的一个属性:style="@android:style/Widget.ProgressBar.Inverse"

注意创建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方法:

09707c1327a6674e30d1e56c233613c2.png

可以发现会报各种引用不到的问题,因为这些变量都是父类定义的private变量。

对于变量mContext有public访问方法

6445a6d7f3cc2a57884fa102e2f6aac4.png

对于其他没有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  如下:

android:layout_width="match_parent"

android:layout_height="wrap_content">

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">

style="?android:attr/progressBarStyle"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:max="10000"

android:layout_marginEnd="12dip" />

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:layout_gravity="center_vertical" />

但是复写的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

962d3de23c37f37fbccc01bf5ee7f4f4.png

如果Dialog构造方法不加主题 ,

一-2、SeekBar

二、快速创建一个输入框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 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

五、NavigationView

1.修改NavigationView中的Item的Icon大小

2.Android NavigationView 中 menu item 字体大小设置

六、TabLayout

1.修改字体大小

2.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值