4

我发现了类似的问题,但无法找到最新的具体答案。 我使用<preference-header>,根据3.0+的设置设计指导方针(我的目标是4.1.2+)来构建我的标题;我想为这些标题设置一个自定义布局。请注意,我不想回到旧版PreferenceScreen方法here,因为我不支持较旧的Android版本。是否可以自定义首选项标题布局?

据我研究,这种布局是由PreferenceActivity类的私有成员举行,它与一个设置样式属性检索似乎没有公开访问:

private int mPreferenceHeaderItemResId = 0; 
... 
@Override 
protected void onCreate(@Nullable Bundle savedInstanceState) { 
... 
TypedArray sa = obtainStyledAttributes(null, 
      com.android.internal.R.styleable.PreferenceActivity, 
      com.android.internal.R.attr.preferenceActivityStyle, 
      0); 
... 
mPreferenceHeaderItemResId = sa.getResourceId(
    com.android.internal.R.styleable.PreferenceActivity_headerLayout, 
      com.android.internal.R.layout.preference_header_item); 
... 
} 

这个资源是那么传递给一个专用适配器来填充标题ListView。

有没有办法传递不同的布局资源?

回答

5

UPDATE 2016年4月14日:存在与重新创建问题通过savedInstanceState,但我发现another similar solution从我用setListAdapter方法的代码(I改性下面的代码)。


我也解决了这个问题。我不知道以下解决方案是否正确,但速度最快。由于PreferenceActivity是ListActivity的子项,因此您可以覆盖setListAdapter方法以使用自己的适配器来处理标题项目。这很丑陋,因为在PreferenceActivity.onCreate()中调用setListAdapter方法并将adapter参数设置为HeaderAdapter的新实例,所以下面的调整忽略此实例。

@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属性被定义为类成员

private List<Header> mHeaders; 

和onBuildHeaders被分配:

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

我复制并从SDK源改性适配器内部类和布局:

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 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> 
相关问题