PreferenceActivity UI 优化修改

PreferenceActivity UI 优化修改nbsp 虽然 PreferenceAc 的 UI 比较搓 但是由于其良好的封装性和实用性 所以在一些场景还是有一定的使用价值 所以如何能优化它的 UI 让它和你程序相配就十分必要了 毕竟对于程序员来说能懒点就懒点 哈哈 nbsp 首先 nbsp publicabstra

 虽然PreferenceActivity的UI比较搓,但是由于其良好的封装性和实用性,所以在一些场景还是有一定的使用价值。所以如何能优化它的UI让它和你程序相配就十分必要了。毕竟对于程序员来说能懒点就懒点,哈哈。

 首先,

 

public abstract class PreferenceActivity extends ListActivity implements PreferenceManager.OnPreferenceTreeClickListener, PreferenceFragment.OnPreferenceStartFragmentCallback

  这就表明可以替换背景,可以替换Divider,Selector。

  它的adapter是PreferenceGroupAdapter,见于PreferenceScreen:

 

 public void bind(ListView listView) { listView.setOnItemClickListener(this); listView.setAdapter(getRootAdapter()); onAttachedToActivity(); }

   这个方法在PreferenceActivity里被掉,用于加载adapter。

package android.preference; import java.util.ArrayList; import java.util.Collections; import java.util.List; import android.os.Handler; import android.preference.Preference.OnPreferenceChangeInternalListener; import android.view.View; import android.view.ViewGroup; import android.widget.Adapter; import android.widget.BaseAdapter; import android.widget.ListView; / * An adapter that returns the {@link Preference} contained in this group. * In most cases, this adapter should be the base class for any custom * adapters from {@link Preference#getAdapter()}. * 

* This adapter obeys the * {@link Preference}'s adapter rule (the * {@link Adapter#getView(int, View, ViewGroup)} should be used instead of * {@link Preference#getView(ViewGroup)} if a {@link Preference} has an * adapter via {@link Preference#getAdapter()}). *

* This adapter also propagates data change/invalidated notifications upward. *

* This adapter does not include this {@link PreferenceGroup} in the returned * adapter, use {@link PreferenceCategoryAdapter} instead. * * @see PreferenceCategoryAdapter */ class PreferenceGroupAdapter extends BaseAdapter implements OnPreferenceChangeInternalListener { private static final String TAG = "PreferenceGroupAdapter"; / * The group that we are providing data from. */ private PreferenceGroup mPreferenceGroup; / * Maps a position into this adapter -> {@link Preference}. These * {@link Preference}s don't have to be direct children of this * {@link PreferenceGroup}, they can be grand children or younger) */ private List mPreferenceList; / * List of unique Preference and its subclasses' names. This is used to find * out how many types of views this adapter can return. Once the count is * returned, this cannot be modified (since the ListView only checks the * count once--when the adapter is being set). We will not recycle views for * Preference subclasses seen after the count has been returned. */ private ArrayList mPreferenceLayouts; private PreferenceLayout mTempPreferenceLayout = new PreferenceLayout(); / * Blocks the mPreferenceClassNames from being changed anymore. */ private boolean mHasReturnedViewTypeCount = false; private volatile boolean mIsSyncing = false; private Handler mHandler = new Handler(); private Runnable mSyncRunnable = new Runnable() { public void run() { syncMyPreferences(); } }; private static class PreferenceLayout implements Comparable { private int resId; private int widgetResId; private String name; public int compareTo(PreferenceLayout other) { int compareNames = name.compareTo(other.name); if (compareNames == 0) { if (resId == other.resId) { if (widgetResId == other.widgetResId) { return 0; } else { return widgetResId - other.widgetResId; } } else { return resId - other.resId; } } else { return compareNames; } } } public PreferenceGroupAdapter(PreferenceGroup preferenceGroup) { mPreferenceGroup = preferenceGroup; // If this group gets or loses any children, let us know mPreferenceGroup.setOnPreferenceChangeInternalListener(this); mPreferenceList = new ArrayList (); mPreferenceLayouts = new ArrayList (); syncMyPreferences(); } private void syncMyPreferences() { synchronized(this) { if (mIsSyncing) { return; } mIsSyncing = true; } List newPreferenceList = new ArrayList (mPreferenceList.size()); flattenPreferenceGroup(newPreferenceList, mPreferenceGroup); mPreferenceList = newPreferenceList; notifyDataSetChanged(); synchronized(this) { mIsSyncing = false; notifyAll(); } } private void flattenPreferenceGroup(List preferences, PreferenceGroup group) { // TODO: shouldn't always? group.sortPreferences(); final int groupSize = group.getPreferenceCount(); for (int i = 0; i < groupSize; i++) { final Preference preference = group.getPreference(i); preferences.add(preference); if (!mHasReturnedViewTypeCount && !preference.hasSpecifiedLayout()) { addPreferenceClassName(preference); } if (preference instanceof PreferenceGroup) { final PreferenceGroup preferenceAsGroup = (PreferenceGroup) preference; if (preferenceAsGroup.isOnSameScreenAsChildren()) { flattenPreferenceGroup(preferences, preferenceAsGroup); } } preference.setOnPreferenceChangeInternalListener(this); } } / * Creates a string that includes the preference name, layout id and widget layout id. * If a particular preference type uses 2 different resources, they will be treated as * different view types. */ private PreferenceLayout createPreferenceLayout(Preference preference, PreferenceLayout in) { PreferenceLayout pl = in != null? in : new PreferenceLayout(); pl.name = preference.getClass().getName(); pl.resId = preference.getLayoutResource(); pl.widgetResId = preference.getWidgetLayoutResource(); return pl; } private void addPreferenceClassName(Preference preference) { final PreferenceLayout pl = createPreferenceLayout(preference, null); int insertPos = Collections.binarySearch(mPreferenceLayouts, pl); // Only insert if it doesn't exist (when it is negative). if (insertPos < 0) { // Convert to insert index insertPos = insertPos * -1 - 1; mPreferenceLayouts.add(insertPos, pl); } } public int getCount() { return mPreferenceList.size(); } public Preference getItem(int position) { if (position < 0 || position >= getCount()) return null; return mPreferenceList.get(position); } public long getItemId(int position) { if (position < 0 || position >= getCount()) return ListView.INVALID_ROW_ID; return this.getItem(position).getId(); } public View getView(int position, View convertView, ViewGroup parent) { final Preference preference = this.getItem(position); // Build a PreferenceLayout to compare with known ones that are cacheable. mTempPreferenceLayout = createPreferenceLayout(preference, mTempPreferenceLayout); // If it's not one of the cached ones, set the convertView to null so that // the layout gets re-created by the Preference. if (Collections.binarySearch(mPreferenceLayouts, mTempPreferenceLayout) < 0) { convertView = null; } return preference.getView(convertView, parent); } @Override public boolean isEnabled(int position) { if (position < 0 || position >= getCount()) return true; return this.getItem(position).isSelectable(); } @Override public boolean areAllItemsEnabled() { // There should always be a preference group, and these groups are always // disabled return false; } public void onPreferenceChange(Preference preference) { notifyDataSetChanged(); } public void onPreferenceHierarchyChange(Preference preference) { mHandler.removeCallbacks(mSyncRunnable); mHandler.post(mSyncRunnable); } @Override public boolean hasStableIds() { return true; } @Override public int getItemViewType(int position) { if (!mHasReturnedViewTypeCount) { mHasReturnedViewTypeCount = true; } final Preference preference = this.getItem(position); if (preference.hasSpecifiedLayout()) { return IGNORE_ITEM_VIEW_TYPE; } mTempPreferenceLayout = createPreferenceLayout(preference, mTempPreferenceLayout); int viewType = Collections.binarySearch(mPreferenceLayouts, mTempPreferenceLayout); if (viewType < 0) { // This is a class that was seen after we returned the count, so // don't recycle it. return IGNORE_ITEM_VIEW_TYPE; } else { return viewType; } } @Override public int getViewTypeCount() { if (!mHasReturnedViewTypeCount) { mHasReturnedViewTypeCount = true; } return Math.max(1, mPreferenceLayouts.size()); } }

  它的getView里掉的是Preference的getView。Preference类似于View,是所有相关UI类的基类。以下是和UI相关的重要代码。

 public View getView(View convertView, ViewGroup parent) { if (convertView == null) { convertView = onCreateView(parent); } onBindView(convertView); return convertView; } protected View onCreateView(ViewGroup parent) { final LayoutInflater layoutInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); final View layout = layoutInflater.inflate(mLayoutResId, parent, false); final ViewGroup widgetFrame = (ViewGroup) layout .findViewById(com.android.internal.R.id.widget_frame); if (widgetFrame != null) { if (mWidgetLayoutResId != 0) { layoutInflater.inflate(mWidgetLayoutResId, widgetFrame); } else { widgetFrame.setVisibility(View.GONE); } } return layout; }

 所以基本上每个Preference UI控件最多和mLayoutResId和mWidgetLayoutResId相关。

 首先查找它们的布局,比如PreferenceCategory,attr为com.android.internal.R.attr.preferenceCategoryStyle,

对应主题中的style为

@android:style/Preference.Category

 

 

 如下列出所有的attr: 
 
   ...... 
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
  对应的style为: 

   我没搞清楚的是这个style是在什么地方设进去的。所以如果要修改PreferenceCategory的UI,只需从系统源码中拷贝出这个布局XML,修改它的title的id:@+android:id/title为@android:id/title,同时  

        android:layout=”@layout/preference_category”

        android:title=”你好1″ >

由于PreferenceCategory是直接加载preference_category的,所以替换了默认的preference.xml,所以就算你配上android:widgetLayout也没用。

  修改CheckBoxPreference的UI需要:layout->preference.xml widgetLayout->preference_widget_checkbox.xml,同时修改id。

  拿到布局文件后,字体,字体大小,颜色等布局元素你想怎么弄就怎么弄了。PreferenceActivity UI 优化修改

需要注意的是,如果你想要保存那写选中的数据,必须要对preference UI 控件设置key。因为保存XML时候必须要有key。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/177385.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月26日 下午7:38
下一篇 2026年3月26日 下午7:38


相关推荐

  • 解决activiti7的懒加载机制无法将Task结果直接返回

    解决activiti7的懒加载机制无法将Task结果直接返回List Task tasks taskService createTaskQu 流程实例 key processDefin public car use 查询谁的任务 taskAssignee list 由于 activiti7 的懒加载机制 无法将结 Task

    2026年3月26日
    1
  • TestNG单元测试框架详解

    TestNG单元测试框架详解前言 TestNG 是一个 java 中的开源自动化测试框架 其灵感来自 JUnit 和 NUnit TestNG 还涵盖了 JUnit4 整个核心的功能 但引入了一些新的功能 使其功能更强大 使用更方便 优势 支持依赖测试方法 并行测试 负载测试 局部故障 灵活的插件 API 支持多线程测试 详细使用说明请参考官方链接 https testng org doc index html1 TestNG 使用流程 1 1TestNG 安装本文以 IDEA Maven 为例介绍 TestNG Int

    2026年3月19日
    4
  • openclaw 到底解决了什么痛点

    openclaw 到底解决了什么痛点

    2026年3月13日
    2
  • Pycharm搜索操作

    Pycharm搜索操作Ctrl N 按文件名搜索 py 文件 Ctrl Shift N 可搜索各种类型的文件 也可以添加 搜索路径 Ctrl Shift F 全局字符串搜索 findinpath 和默认的 win10 输入法切换简繁体的快捷键冲突 可在 File Settings Keymap 中查找 findinpath 进行设置 Ctrl F 搜索本页字符串 Ctrl S

    2026年3月27日
    2
  • LaTex中输入空格以及换行

    LaTex中输入空格以及换行1.使用\表示空格以及调整空格的大小quad空格 a\qquadb 两个m的宽度 quad空格 a\quadb 一个m的宽度 大空格 a\b 1/3m宽度 中等空格 a\;b 2/7m宽度 小空格 a\,b 1/6m宽度 没有空格 ab …

    2022年5月15日
    450
  • 动漫迷必备网站[通俗易懂]

    动漫迷必备网站[通俗易懂]nyaa这是个比较全的网站,里面包含动漫、游戏、同人,二次元和三次元都有。https://nyaa.si/NeetsNeets你的私人追剧专家,包含日剧、韩剧、美剧、动漫以及国产剧等,链接都是由用户上传的,资源比较丰富。http://neets.cc/哈哩哈哩H小站也是一个不错的选择,界面偏暖色调,个人比较喜欢。http://www.halihali.cc/天马…

    2022年8月23日
    8

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号