PreferenceActivity
を使用して設定アクティビティを作成するために設定ヘッダーを使用しています。次のように、ヘッダーをカテゴリ/グループに分割しようとしています(ワイヤレスとネットワーク、デバイス、パーソナルなどのカテゴリがあります)。
とにかく、それでもAndroid=開発者サイトはこのような設定アクティビティの作成方法についてですが、画像と同じように同じ設定アクティビティを作成する方法を見つけることができませんでした。行うのは、設定ヘッダーの単純なリストです。
私が見つけた唯一のものは this ですが、それはちょっとうまくいきます...奇妙です。したがって、これはオプションのようには見えません。
だから私の質問は:ヘッダーをカテゴリに分割する可能性と、マスターのオン/オフスイッチを使用する可能性がある設定ヘッダーを使用してPreferenceActivity
を作成する方法ですか?
私のコードの一部:
preference_headers.xml:
<?xml version="1.0" encoding="utf-8"?>
<preference-headers xmlns:Android="http://schemas.Android.com/apk/res/Android">
<header
Android:fragment="cz.vse.myevents.activity.SettingsActivity$EventsFragment"
Android:title="@string/settings_events"
Android:icon="@Android:drawable/ic_menu_agenda" />
<header
Android:fragment="cz.vse.myevents.activity.SettingsActivity$OrganizationsFragment"
Android:title="@string/settings_subscribed_organizations"
Android:icon="@Android:drawable/ic_menu_view" />
</preference-headers>
SettingsActivity:
@Override
public void onBuildHeaders(List<Header> target) {
super.onBuildHeaders(target);
loadHeadersFromResource(R.xml.preference_headers, target);
}
私はフラグメントリソースを投稿していません、それは不必要だと思います。
最良の解決策は、3つの異なるコードブロックの作成です。1つはハニカム前、もう1つはハニカム用、もう1つはタブレット用です。
プリファレンスヘッダーの使用はタブレットでのみ有効であるため、タブレットでのみ使用できます。ここではグループ化は使用されていません。
Post-HoneycombのPreferenceヘッダーは役に立たないため、PreferenceScreen
での一般的なPreferenceFragment
の使用が最善です。グループはPreferenceCategory
で簡単に作成できます。
そして最後に、Honeycomb以前は、PrefrenceFragment
を使用しない非推奨の方法が唯一の方法です。
悲しいことに、コードの重複はたくさんありますが、Leandrosの回答で述べられているUnifiedPreference
ライブラリはバグが多く、PreferenceFragment
を完全に無視するので、(少なくとも私にとっては)役に立たないものです。
これは設定カテゴリの例です。設定カテゴリを使用し、それぞれのフラグメントを設定してこれを実現できます。ケースを誤解した場合はお知らせください。
ここにサンプルのレイアウトがあります
<PreferenceCategory Android:title="Heading1">
<Preference
Android:title="title1"
Android:summary="summary1"
Android:key="keyName"/>
<Preference
Android:title="title2"
Android:summary="summary2"
Android:key="keyName"/>
</PreferenceCategory>
<PreferenceCategory Android:title="Heading2">
<Preference
Android:title="title3"
Android:summary="summary3"
Android:key="keyName"/>
</PreferenceCategory>
T。Folsom からの回答を詳しく説明するために、これが私の実装です:
res/layout/preference_header_item.xml
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:background="?android:attr/activatedBackgroundIndicator"
Android:baselineAligned="false"
Android:gravity="center_vertical"
Android:minHeight="48dp"
Android:paddingRight="?android:attr/scrollbarSize" >
<LinearLayout
Android:layout_width="@dimen/header_icon_width"
Android:layout_height="wrap_content"
Android:layout_marginLeft="6dip"
Android:layout_marginRight="6dip" >
<ImageView
Android:id="@+id/icon"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_gravity="center" />
</LinearLayout>
<RelativeLayout
Android:layout_width="0dip"
Android:layout_height="wrap_content"
Android:layout_marginBottom="6dip"
Android:layout_marginLeft="2dip"
Android:layout_marginRight="6dip"
Android:layout_marginTop="6dip"
Android:layout_weight="1" >
<TextView
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:attr/textAppearanceMedium" />
<TextView
Android:id="@+Android:id/summary"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_below="@Android:id/title"
Android:ellipsize="end"
Android:maxLines="2"
Android:textAppearance="?android:attr/textAppearanceSmall" />
</RelativeLayout>
</LinearLayout>
res/values/dimens.xml
<resources>
<dimen name="header_icon_width">28dp</dimen>
</resources>
preferenceActivityクラスで:
@Override
protected void onCreate(Bundle savedInstanceState) {
if (savedInstanceState != null) {
/*
* the headers must be restored before the super call in order
* to be ready for the call to setListAdapter()
*/
if (savedInstanceState.containsKey("headers")) {
setHeaders((ArrayList<Header>)savedInstanceState.getSerializable("headers"));
}
}
// as suggest by https://stackoverflow.com/questions/15551673/Android-headers-categories-in-preferenceactivity-with-preferencefragment
if(onIsMultiPane()) getIntent().putExtra(PreferenceActivity.EXTRA_SHOW_FRAGMENT, PreferencesFragment.class.getName());
super.onCreate(savedInstanceState);
...
}
@Override
protected void onResume() {
super.onResume();
// https://stackoverflow.com/questions/15551673/Android-headers-categories-in-preferenceactivity-with-preferencefragment
// Select the displayed fragment in the headers (when using a tablet) :
// This should be done by Android, it is a bug fix
if(getHeaders() != null) {
final String displayedFragment = getIntent().getStringExtra(EXTRA_SHOW_FRAGMENT);
if (displayedFragment != null) {
for (final Header header : getHeaders()) {
if (displayedFragment.equals(header.fragment)) {
switchToHeader(header);
break;
}
}
}
}
...
}
/**
* Populate the activity with the top-level headers.
*/
@Override
public void onBuildHeaders(List<Header> target) {
// we have to save the headers as the API call getHeaders() is hidden.
setHeaders(target);
loadHeadersFromResource(R.xml.settings_headers, target);
}
private List<Header> headers;
private void setHeaders(List<Header> headers) {
this.headers = headers;
}
private List<Header> getHeaders() {
return headers;
}
@Override
protected void onSaveInstanceState(Bundle outState) {
outState.putSerializable("headers", (ArrayList<PreferenceActivity.Header>)headers);
super.onSaveInstanceState(outState);
}
@Override
public void setListAdapter(ListAdapter adapter) {
if (adapter == null) {
super.setListAdapter(null);
} else {
super.setListAdapter(new HeaderAdapter(this, getHeaders()));
}
}
private static class HeaderAdapter extends ArrayAdapter<Header> {
static final int HEADER_TYPE_CATEGORY = 0;
static final int HEADER_TYPE_NORMAL = 1;
private static final int HEADER_TYPE_COUNT = HEADER_TYPE_NORMAL + 1;
private static class HeaderViewHolder {
ImageView icon;
TextView title;
TextView summary;
}
private LayoutInflater mInflater;
static int getHeaderType(Header header) {
if (header.fragment == null && header.intent == null) {
return HEADER_TYPE_CATEGORY;
} else {
return HEADER_TYPE_NORMAL;
}
}
@Override
public int getItemViewType(int position) {
Header header = getItem(position);
return getHeaderType(header);
}
@Override
public boolean areAllItemsEnabled() {
return false; // because of categories
}
@Override
public boolean isEnabled(int position) {
return getItemViewType(position) != HEADER_TYPE_CATEGORY;
}
@Override
public int getViewTypeCount() {
return HEADER_TYPE_COUNT;
}
@Override
public boolean hasStableIds() {
return true;
}
public HeaderAdapter(Context context, List<Header> objects) {
super(context, 0, objects);
mInflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
HeaderViewHolder holder;
Header header = getItem(position);
int headerType = getHeaderType(header);
View view = null;
if (convertView == null) {
holder = new HeaderViewHolder();
switch (headerType) {
case HEADER_TYPE_CATEGORY:
view = new TextView(getContext(), null,
Android.R.attr.listSeparatorTextViewStyle);
holder.title = (TextView) view;
break;
case HEADER_TYPE_NORMAL:
view = mInflater.inflate(R.layout.preference_header_item,
parent, false);
holder.icon = (ImageView) view.findViewById(R.id.icon);
holder.title = (TextView) view
.findViewById(Android.R.id.title);
holder.summary = (TextView) view
.findViewById(Android.R.id.summary);
break;
}
view.setTag(holder);
} else {
view = convertView;
holder = (HeaderViewHolder) view.getTag();
}
// All view fields must be updated every time, because the view may
// be recycled
switch (headerType) {
case HEADER_TYPE_CATEGORY:
holder.title.setText(header.getTitle(getContext()
.getResources()));
break;
case HEADER_TYPE_NORMAL:
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);
}
break;
}
return view;
}
}
このすべてのコードを配置すると、ヘッダーの作成は簡単です。
<preference-headers xmlns:Android="http://schemas.Android.com/apk/res/Android" >
<header Android:title="atitle" />
</preference-headers>
これが誰かを助けることを願っています。きちんと機能するようになるまでに少し時間がかかったと思います。
これは実際には非常に簡単です。私が見つけたところによると、ルートPreferenceActivity
自体はカテゴリ/セクションタイトルの追加をサポートしていません。Header
sしか追加できないようです-これはあまり面白くありません。
したがって、最初に行う必要があるのは、PreferenceActivity
自体を大幅に強化することなく、PreferenceFragment
をロードすることです。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setTitle("Settings");
// Display the fragment as the main content.
getFragmentManager().beginTransaction()
.replace(Android.R.id.content, new PreferencesFragment())
.commit();
}
public static class PreferencesFragment extends PreferenceFragment {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.prefs);
}
}
これを完了すると、PreferenceFragment
ですべての作業を実行できるようになります。すばらしいニュースはこれでカテゴリを使用できるようになります!
R.xml.prefsファイルは次のようになります。
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:Android="http://schemas.Android.com/apk/res/Android" >
<PreferenceCategory
Android:summary="Login credentials"
Android:title="Login credentials" >
<EditTextPreference
Android:key="username"
Android:summary="Username"
Android:title="Username" />
<EditTextPreference
Android:key="password"
Android:summary="Password"
Android:title="Password" />
</PreferenceCategory>
<PreferenceCategory
Android:summary="Settings"
Android:title="Settings" >
<CheckBoxPreference
Android:key="persist"
Android:summary="Yes/No"
Android:title="Keep me signed in" />
</PreferenceCategory>
</PreferenceScreen>
追加する新しいカテゴリごとにPreferenceCategory
を作成するだけです。