Skip to content

Latest commit

 

History

History
64 lines (56 loc) · 4.32 KB

UI问题集锦.md

File metadata and controls

64 lines (56 loc) · 4.32 KB

Android UI问题集锦

这篇博客用来记录作者在Android开发过程中遇到的一些UI上的问题,本博客持续更新,欢迎关注。 作者:刘振华 邮箱:[email protected] 个人网站:blog.liuzhenhua.net github:github.com/liuzhenhuanet

View构造方法参数分别代表什么,都有什么作用?

View有四个构造方法,分别是:

public View(Context context)
public View(Context context, @Nullable AttributeSet attrs)
public View(Context context, @Nullable AttributeSet attrs, int defStyleAttr)
public View(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes)

这么几个构造方法其实可以理解为一个构造方法,前面三个方法直接或间接地调用最后一个构造方法,并传入默认参数。 那么我们就只分析最后一个构造方法,这个构造方法是在API 21加入的。

第一个参数Context大家都很熟悉了,这个参数一般来说应该传入一个Activity,但也可以是Application等其他Context子类, 但是如果传入的不是Activity并且需要在View内部使用Context启动一个Activity,则必须记住给Intent增加参数 Intent.FLAG_ACTIVITY_NEW_TASK,不然启动时会崩溃。另外Context还决定了页面的主题,所以同样的View,通过不同的 Context构造,显示样式可能差别非常大。

第二个参数AttributeSet,可以为null,这个参数是一个属性集,一般在xml中设置的属性会通过这个参数传入。

第三个参数defStyleAtrr,是一个R.attr.xxx属性,从Context的主题中获取属性值对应的样式。例如主题中定义了一个item 属性:<item name="myStyleAttr">@style/beautifulStyle</item>defStyleAttr参数传入的值是R.attr.myStyleAttr, 则当AttributeSet参数没有设置相关属性集时则从beautifulStyle中获取。

第四个参数defStyleRes与第三个参数类似,当前面的参数都没有设置相关的属性时,则会从第四个参数里面获取,这个参数指的是一个 Style资源。

如何通过Java代码设置EditText显示滚动条?

如果EditText中的内容超过了View内容高度,想要显示滚动条该怎么做呢?我们知道可以在布局文件中设置属性: android:scrollbars="vertical",这样就可以让其在竖直方向显示滚动条了。但是如果EditText是在Java代码中直接 new出来的呢?网上找到的答案基本都是在Java代码中调用View.setVerticalScrollBarEnabled(true)方法,我试了一下, 是无效的。我跟踪到View类的构造方法的代码里找到下面这段代码:

if (initializeScrollbars) {
    initializeScrollbarsInternal(a);
}

initializeScrollbarsInternal(a);方法主要是初始化scrollbar相关样式的,initializeScrollbars的值是ViewR.styleable.View_scrollbars样式属性值,所以不论我是在xml定义EditText还是直接new EditText后再调用 View.setVerticalScrollBarEnabled(true)方法都不能显示滚动条,因为除了在构造方法中能够调用initializeScrollbarsInternal(a); 方法之外,没有其他地方调用这个方法了,因此也就没有设置scrollbar样式,从而导致不能显示滚动条。

那么如果我是用java代码直接new的EditText要怎样才能显示scrollbar呢?答案就是通过传入合适的构造方法参数,使 initializeScrollbars为true,attrs是xml设置的属性,我们不是从xml构造的控件,所以这个参数不行。defStyleRes 参数是API 21才加入的,为了兼容老版本这个参数也不行,那只剩下defStyleAttr这个参数了,这个参数是通过指定采用主题中的哪个 属性值对应的样式(style)来设置View属性,而跟踪到EditText构造方法:

public EditText(Context context, AttributeSet attrs) {
    this(context, attrs, com.android.internal.R.attr.editTextStyle);
}

发现默认是使用的com.android.internal.R.attr.editTextStyle,所以我们只要在EditText使用的主题中增加如下代码:

<item name="android:editTextStyle">@style/myStyle</item>

其中myStyle样式中设置至少一个item:

<item name="android:scrollbars">vertical</item>

那么,一切都搞定了。

下一个话题,敬请期待……