Is it possible to customize preference-header layout?

删除回忆录丶 提交于 2019-12-05 04:48:32
Petr Daňa

UPDATE 14.4.2016: there was problem with recreate by savedInstanceState, but I found another similar solution from which I used setListAdapter method code (I modified the code below).


I solve this problem just too. I don't know if the following solution is correct, but was the fastest. Because PreferenceActivity is child of ListActivity, you can override setListAdapter method for using own adapter for header items. This is ugly hack, because setListAdapter method is called in PreferenceActivity.onCreate() with sets adapter parameter to new instance of HeaderAdapter, so following adjustment ignore this instance.

@Override
public void setListAdapter(ListAdapter adapter) {
    int i, count;

    if (mHeaders == null) {
        mHeaders = new ArrayList<>();
        // When the saved state provides the list of headers, onBuildHeaders is not called
        // so we build it from the adapter given, then use our own adapter

        count = adapter.getCount();
        for (i = 0; i < count; ++i) {
            mHeaders.add((Header) adapter.getItem(i));
        }
    }

    super.setListAdapter(new CustomHeaderAdapter(this, mHeaders, R.layout.preference_header_item, true));
}

mHeaders property is defined as class member

private List<Header> mHeaders;

and is assigned in onBuildHeaders:

@Override
public void onBuildHeaders(List<Header> target) {
    mHeaders = target;
    loadHeadersFromResource(R.xml.preference_headers, target);
    ...
}

I copied and modified adapter inner class and layout from SDK source:

private static class CustomHeaderAdapter extends ArrayAdapter<Header> {
    private static class HeaderViewHolder {
        ImageView icon;
        TextView title;
        TextView summary;
    }

    private LayoutInflater mInflater;
    private int mLayoutResId;
    private boolean mRemoveIconIfEmpty;

    public CustomHeaderAdapter(Context context, List<Header> objects, int layoutResId,
                         boolean removeIconBehavior) {
        super(context, 0, objects);
        mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        mLayoutResId = layoutResId;
        mRemoveIconIfEmpty = removeIconBehavior;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        HeaderViewHolder holder;
        View view;

        if (convertView == null) {
            view = mInflater.inflate(mLayoutResId, parent, false);
            holder = new HeaderViewHolder();
            holder.icon = (ImageView) view.findViewById(R.id.icon);
            holder.title = (TextView) view.findViewById(R.id.title);
            holder.summary = (TextView) view.findViewById(R.id.summary);
            view.setTag(holder);
        } else {
            view = convertView;
            holder = (HeaderViewHolder) view.getTag();
        }

        // All view fields must be updated every time, because the view may be recycled
        Header header = getItem(position);
        if (mRemoveIconIfEmpty) {
            if (header.iconRes == 0) {
                holder.icon.setVisibility(View.GONE);
            } else {
                holder.icon.setVisibility(View.VISIBLE);
                holder.icon.setImageResource(header.iconRes);
            }
        } else {
            holder.icon.setImageResource(header.iconRes);
        }
        holder.title.setText(header.getTitle(getContext().getResources()));
        CharSequence summary = header.getSummary(getContext().getResources());
        if (!TextUtils.isEmpty(summary)) {
            holder.summary.setVisibility(View.VISIBLE);
            holder.summary.setText(summary);
        } else {
            holder.summary.setVisibility(View.GONE);
        }

        return view;
    }
}

preference_header_item.xml with modified minHeight:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:minHeight="64dp"
    android:background="?android:attr/activatedBackgroundIndicator"
    android:gravity="center_vertical"
    android:paddingRight="?android:attr/scrollbarSize"
    android:paddingEnd="?android:attr/scrollbarSize">

    <ImageView
        android:id="@+id/icon"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="6dip"
        android:layout_marginEnd="6dip"
        android:layout_gravity="center" />

    <RelativeLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="2dip"
        android:layout_marginStart="2dip"
        android:layout_marginRight="6dip"
        android:layout_marginEnd="6dip"
        android:layout_marginTop="6dip"
        android:layout_marginBottom="6dip"
        android:layout_weight="1">

        <TextView android:id="@+id/title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:singleLine="true"
            android:textAppearance="?android:attr/textAppearanceMedium"
            android:ellipsize="marquee"
            android:fadingEdge="horizontal" />

        <TextView android:id="@+id/summary"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@android:id/title"
            android:layout_alignLeft="@android:id/title"
            android:layout_alignStart="@android:id/title"
            android:textAppearance="?android:attr/textAppearanceSmall"
            android:ellipsize="end"
            android:maxLines="2" />

    </RelativeLayout>

</LinearLayout>
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!