web-dev-qa-db-ja.com

PreferenceFragmentでディバイダーを管理する方法は?

PreferenceFragmentの設定を扱い始めました。ここに私が持っているものがあります:

my_preferences

私はしようとしています:

  1. アイテム間の仕切りを取り除きます。これはスタイルから定義できると思いますが、方法はわかりません。どこかで読んだときに、実行時にfindViewById(Android.R.id.list)を呼び出して設定ListViewを取得しようとしましたが、nullを返しました。

  2. set new、full width仕切りをヘッダーの真上に表示 here 。たとえば、この場合、「Statistiche」の真上に全幅の分割線が必要ですが、リストの一番上にある「Generali」の上にはありません。

私の頭に浮かぶ唯一の方法は、次のように、仕切りを偽の設定として設定することです。

<Preference
    Android:layout="@layout/divider" //here I set width and a divider resource
    />

<PreferenceCategory ... />

ここでの主な問題は、私のPreferenceFragment(またはその中にあるActionBarActivity)に左/右のパディングがあり、preferences.xmlnotは幅全体をカバーしません。

だから私の質問は:

  • 画像で確認できるデフォルトのアイテム間仕切りを取り除くにはどうすればよいですか?

  • ヘッダーのすぐ上に全幅の仕切りを設定する方法、または内部のフラグメント/アクティビティのパディングを取り除く方法はありますか?もちろん、私のアクティビティレイアウトには(明示的な)パディングはありません。

17
natario

この質問を完全に忘れてしまった場合、他の人を助けるために今すぐ回答を投稿します。 PreferenceFragmentをホストするアクティビティのonResume()メソッドにコードを移動して解決しました。 findViewById(Android.R.id.list)を使用してnull以外のListViewを呼び出すことができるポイントは他にもいくつかあると思います。

_public boolean mListStyled;

@Override
public void onResume() {
    super.onResume();
    if (!mListStyled) {
        View rootView = getView();
        if (rootView != null) {
            ListView list = (ListView) rootView.findViewById(Android.R.id.list);
            list.setPadding(0, 0, 0, 0);
            list.setDivider(null);
            //any other styling call
            mListStyled = true;
        }
    }
}
_

おそらくrootViewチェックを取り除くことができますが、同時に_list != null_をチェックすることもできます。とにかく、私はこの方法でNPEに直面しませんでした。

したがって、setDivider(null)はアイテムとアイテムの仕切りを取り除きます。次の方法で、画面の全幅をカバーするセクションディバイダーを追加できました。

  • listからパディングを削除する;
  • XMLにカスタム設定を追加する:

_ <Preference
     Android:title="divider"
     Android:selectable="false"
     Android:layout="@layout/preference_divider"/>
_
6
natario

AndroidXを使用すると簡単になりますが、ドキュメント化されていればよかったのですが。

XML

XMLの設定間の仕切りを追加/削除するには、次の属性を使用します。

<androidx.preference.PreferenceScreen
    xmlns:app="http://schemas.Android.com/apk/res-auto">

    <Preference
        ...
        app:allowDividerAbove="true/false"
        app:allowDividerBelow="true/false"
        ... />

</androidx.preference.PreferenceScreen>

上部の仕切りがallowDividerBelowtrueを設定し、下部の仕切りがallowDividerAbovetrueに設定している場合、2つの設定の間にのみ仕切りが表示されることに注意してください。

コード内

onActivityCreatedPreferenceFragmentCompatで次のメソッドを使用して、プログラムで仕切りを変更/削除することもできます。

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);

    // To remove:
    setDivider(null);

    // To change:
    setDivider(ContextCompat.getDrawable(getActivity(), R.drawable.your_drawable));
    setDividerHeight(your_height);
}
26
Maksim Ivanov

このコードをPreferenceFragmentの下に追加します。

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

        // remove dividers
        View rootView = getView();
        ListView list = (ListView) rootView.findViewById(Android.R.id.list);
        list.setDivider(null);

    }
25
SagiLow

少し遅れましたが、preff画面の仕切りで同じ問題が発生し、次の解決策が見つかりました:ホスティングアクティビティにカスタムスタイルを設定し、スタイルに追加します。

   <item name="Android:listDivider">@null</item>

実際にはコードを介して設定するのと同じですが、findByIdを1つ保存すると、明確なスタイルを設定したように見えます

11
X3Btel

PreferenceFragmentCompatの場合、ListViewは機能しません。しかし、これは魅力のように機能します:

<style name="PrefsTheme" parent="PreferenceThemeOverlay.v14.Material">
    <item name="Android:divider">@null</item>
    <item name="Android:dividerHeight">0dp</item>
</style>

これをアプリのテーマに追加します。

<item name="preferenceTheme">@style/PrefsTheme</item>
4
formatBCE

私はこの正確な問題を抱えており、好みのカテゴリー間ではなく、アイテム自体の間の仕切りが必要でした。承認された解決策は、基本設定項目からディバイダーを削除することによって質問1を満たしたが、問題2を修正せず、基本設定カテゴリー間にディバイダーを追加したことを発見しました。

以下を修正してください。基本的には、PreferenceFragmentCompatのonCreateAdapterメソッドをオーバーライドし、オーバーライドされたonBindViewHolderメソッドを持つカスタムPreferenceGroupAdapterを指定します。このメソッドは、位置と、各ビューホルダーの上下のパーミッションに設定する必要があるものを使用します。両方のビューホルダーがそれらの間の仕切りを許可すると、仕切りが描画されます。

これが私の修正です

public class SettingsFragment extends PreferenceFragmentCompat {

    @Override
    protected RecyclerView.Adapter onCreateAdapter(PreferenceScreen preferenceScreen) {
        return new CustomPreferenceGroupAdapter(preferenceScreen);
    }

    static class CustomPreferenceGroupAdapter extends PreferenceGroupAdapter {

    @SuppressLint("RestrictedApi")
    public CustomPreferenceGroupAdapter(PreferenceGroup preferenceGroup) {
        super(preferenceGroup);
    }

    @SuppressLint("RestrictedApi")
    @Override
    public void onBindViewHolder(PreferenceViewHolder holder, int position) {
        super.onBindViewHolder(holder, position);
        Preference currentPreference = getItem(position);
        //For a preference category we want the divider shown above.
        if(position != 0 && currentPreference instanceof PreferenceCategory) {
            holder.setDividerAllowedAbove(true);
            holder.setDividerAllowedBelow(false);
        } else {
            //For other dividers we do not want to show divider above 
            //but allow dividers below for CategoryPreference dividers.
            holder.setDividerAllowedAbove(false);
            holder.setDividerAllowedBelow(true);
        }
    }
}
3
doubleA

(AndroidXのみ)

マクシム・イワノフの答え そこまでの道のりのほとんど。しかし、仕切りを削除するには特定の設定の場合のみコードで作成したため、次のことを行う必要がありました。

val pref = object : Preference(activity) {
    override fun onBindViewHolder(holder: PreferenceViewHolder) {
        super.onBindViewHolder(holder)
        // By default, preferences created in code show dividers
        holder.setDividerAllowedAbove(false)
        holder.setDividerAllowedBelow(false)
    }
}
2
Stephen Talley

このテーマを使用してディバイダーのスタイルを変更できます。

<style name="PreferenceFragment.Material">
    <item name="Android:divider">@drawable/preference_list_divider_material</item>
</style>
0

新しいAndroid API 24以降(2017年12月25日))の新しいソリューション。

私は、stackoverflowで多くの方法を試した後、動作しない、またはnestestPreferenceScreenで動作するだけで動作しないことを発見しました。

まず、現在表示されているフラグメントからリストビューを見つけ、仕切りを削除する必要があります。

_private fun removeDividerInCurrentFragment() {
    [email protected](Android.R.id.content)?.let {
        it.view?.findViewById<ListView?>(Android.R.id.list)?.let {
            it.divider = null
            it.dividerHeight = 0
        }
    }
}
_

次に、フラグメントがコミットされたときにディバイダーを削除するには、上記のメソッド(removeDividerInCurrentFragment)を呼び出してリストビューのディバイダーを削除します。

nestest PreferenceScreenがあるかどうかを確認します。 _FragmentManager.OnBackStackChangedListener_プロトコルを実装して、フラグメントがPreferenceActivityで変更されたときにリスナーを登録します。

_class YourPreferenceActivity : PreferenceActivity(), FragmentManager.OnBackStackChangedListener {
    override fun onBackStackChanged() {
        [email protected]()
    }
}
_

最後に、onCreatefragmentManager.addOnBackStackChangedListener(this@ YourPreferenceActivity)を呼び出して、バックスタック変更リスナーを登録します。 onDestroyedメソッドで_fragmentManager.removeOnBackStackChangedListener_を呼び出して、バックスタック変更リスナーを削除します。

幸運を!

0
dphans

preferenceFragmentを使用する場合は、ListView .setDivider(null)を使用できます。 PreferenceFragmentCompatを使用する場合は、PreferenceFragmentCompat .setDivider(Drawable divider)またはsetDividerHeight(int height)を使用できます。

0
sadmonster