......
android:paddingRight="?android:attr/scrollbarSize" >
android:id="@+android:id/icon"
......
android:layout_gravity="center" />
......
android:layout_weight="1" >
android:id="@+android:id/title"
.......
android:textColor="#FF00FFFF" />
android:id="@+android:id/summary"
......
android:textColor="#FFFFFF00" />
android:id="@+:id/statusvalues"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@android:id/summary"
android:layout_below="@android:id/summary"
android:maxLines="1"
android:textAppearance="@android:style/TextAppearance.Small"
android:textColor="#FFFFFF00" />
android:id="@+android:id/widget_frame"
.......
android:orientation="vertical" />
然后再设置preference的layout属性,调用自己定义的布局。如下:
android:key="child__preference"
android:layout="@layout/preference_with_value"
android:summary="summary_child_preference"
android:title="title_child_preference" />
然后再到代码里findPreference的时候,findViewById(R.id.statusvalues),接着再设置textView.setText();
。。。。。
可以看到这么做真的比较烦。并且,每次用到这样的preference,都要这么重写一遍,各种蛋疼(也叫卵子痛)。
现在在做framework,我们就可以随便修改系统代码,来提供这样的布局给上层app调用。不是吗?这样,就不需要到处声明layout,到处findViewById了。
愿望很美好~~问题来了,如何做呢?
首先,要知道我们的目标:参照android原生的设计:肯定是要提供一个类似于title和summary的属性,给上层app调用。同时,在java文件中,提供类似于setTitle和setSummary的方法。
然后就是实现了。如何在framework中添加自己的set方法?这个不难。找到Preference.java,仿照setTitle方法,添加setStatusValues()。实现基本相同,就是把id改一下。这里简单的贴出部分伪代码:
packages com.android.view;
......
public class Preference ....
{
......
Charsequence mTitle;
//下面就是我们仿照title的statusValues
Charsequence mStatusValues;
......
public Charsequence getTitle(){
......
}
public void setTitle(Charsequence title){
......
}
public void setTitle(int resId){
......
}
//下面就是我们仿照的title的statusvalues
public Charsequence getStatusValues(){
return mStatusValues;
}
public void setStatusValues(Charsequence value){
//......就不实现了,title的实现体,换个变量名而已
}
public void setStatusValues(int resId){
//......就不实现了,title的实现体,换个变量名而已
}
.......
protected void onBindView(View view) {
final TextView titleView = (TextView) view.findViewById(
com.android.internal.R.id.title);
if (titleView != null) {
final CharSequence title = getTitle();
if (!TextUtils.isEmpty(title)) {
titleView.setText(title);
titleView.setVisibility(View.VISIBLE);
} else {
titleView.setVisibility(View.GONE);
}
}
......
//下面就是我们仿照的title的statusvalues
final TextView statusView = (TextView) view.findViewById(
com.android.internal.R.id.statusvalue);
if (statusView != null) {
final CharSequence statusvalue = getStatusValue();
if (!TextUtils.isEmpty(statusvalue)) {
statusView.setText(statusvalue);
statusView.setVisibility(View.VISIBLE);
} else {
statusView.setVisibility(View.GONE);
}
}
}
......
}
还需要在一个地方修改布局:preference.xml(在frameworks/base/core/res/res/layout/中)
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:minHeight="?android:attr/listPreferredItemHeight"
android:paddingRight="?android:attr/scrollbarSize" >
android:id="@+android:id/icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center" />
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="6dip"
android:layout_marginLeft="15dip"
android:layout_marginRight="6dip"
android:layout_marginTop="6dip"
android:layout_weight="1" >
android:id="@+android:id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="marquee"
android:fadingEdge="horizontal"
android:singleLine="true"
android:textAppearance="@android:style/TextAppearance.Medium"
android:textColor="#FF00FFFF" />
android:id="@+android:id/summary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@android:id/title"
android:layout_below="@android:id/title"
android:maxLines="4"
android:textAppearance="@android:style/TextAppearance.Small"
android:textColor="#FFFFFF00" />
android:id="@+:id/statusvalues"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@android:id/summary"
android:layout_below="@android:id/summary"
android:maxLines="1"
android:textAppearance="@android:style/TextAppearance.Small"
android:textColor="#FFFFFF00" />
android:id="@+android:id/widget_frame"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:orientation="vertical" />
在bindView的时候,注意到添加了这样一个com.android.internal.R.id.statusvalue这样一个id。这也是关键的地方。
参考title和summary的id的定义。可以发现,我们需要在2个地方添加属性。分别是:
attrs.xml和public.xml。(均在frameworks/base/core/res/res/values/中)
attrs.xml中,添加的是preference的属性,表明preference具有statusvalue这样的属性。 如下:
......
public.xml中,在最后添加如下属性。
。。。。。。
这里我们添加了2个属性。
java-symbol type="id" name="statusvalue" 这个id就是上面的layout中,我们添加的id。用来给Preference.java文件获取view。
这个public,用来公开statusvalue,这样就可以在xml中,使用android:statusvalue这样的属性了。
好了。我们编译源代码。就可以使用我们自己添加的属性拉!!
总结一下:
如果添加自己的属性,需要在以下几处修改:
1.public.xml中,申明id,暴露attr。
2.attrs.xml中,声明attr。
3.layout文件中,新加布局,使用上面的id和attr。
4.java文件中,增加对attr和新加布局的解析。