2012-04-19 10 views
8

Androidネイティブ設定アプリのようにSwitchReferenceの設定ナビゲーションを行うにはどうすればよいですか? Iアンドロイド:ネイティブ設定アプリのように設定ナビゲーションを行う方法

Click on WiFi

は私のアプリは、その逆であってもONからOFFにスイッチを変更し、:uは(ないスイッチ上)のWiFi地域をクリックすると、新しい画面に移動します

スイッチをクリックしていません。

私はPreferenceFragmentとxmlを画面に使用しています。そして、私の好みはAndroid PreferenceFragment documentationの例に従っています。私はICS 4.0 API 14で自分のアプリを開発します。

誰でもこれを行う方法を知っていますか?

編集:

私のXMLは次のようになります。在庫設定アプリのソースを見てとることによって

<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" > 

    <PreferenceCategory 
     android:layout="@layout/preference_category" 
     android:title="User Settings" > 
     <SwitchPreference 
      android:key="pref_autorun" 
      android:layout="@layout/preference" 
      android:summary="Autorun SMODE on boot" 
      android:title="Autorun SMODE" /> 
     <SwitchPreference 
      android:key="pref_wifi_control" 
      android:layout="@layout/preference" 
      android:selectable="false" 
      android:summary="Controls your Wi-Fi radio automatically based on hotspot availability" 
      android:title="Wi-Fi Radio Control" /> 
    </PreferenceCategory> 
</PreferenceScreen> 
+0

上のコードを少し改良版を置きますか? – Jokahero

+0

私は自分の質問を更新しました。 – Zul

+0

あなたはより早い選択肢を見つけましたか?ユーザーがチェックボックスをクリックしたかどうかを判断するだけですか? – MatheusJardimB

答えて

5

、あなたは彼らがそれをやった方法を見つけることができます。

基本的には、(ListViewと同じように)カスタムArrayAdapterを使用して、スイッチボタンで行を表示します。 2番目の画面では、単にActionBarで使用可能なCustomViewを使用します。

私はan article with a sample codeにあなたのプロジェクトでどのようにできるかを示しました。ただし、これはAPIレベル14以上でしか動作しないため、古いデバイスをターゲットにしている場合は古いスタイルの設定画面を使用してください。

+0

素敵な仕事。それは本当に私をたくさん助けました。おかげでザビエル。 :) – Zul

+0

ニース。あなたが簡単なPreference画面を作成し、それを古いもの、新しいもの、そしてタブレットで使えるようにしなければならないことがたくさんあることはばかげていると言いました。 1つのxmlファイルで宣言するだけで、どこでも動作しなければならない(SHOULD)。期間! – powder366

+0

このソリューションは、このような小さな問題に対しては大きすぎます。ユーザーがいつチェックボックスをクリックしたのかテキスト領域にあるのかを判断する方法はありますか? – MatheusJardimB

1

私はここで2つの質問を参照してください:1.どのように嗜好を聞くには、スイッチ領域外をクリックしますか? 2.アクションバーにスイッチを入れる方法は?

私は質問1お答えします:私は新しいSwitchPreferenceクラスを作成し、何もしないようにonClickメソッドをオーバーライド

を。これにより、スイッチの外側をクリックすると設定が変更されなくなります。

public class SwitchPreference extends android.preference.SwitchPreference { 
    @Override 
    protected void onClick() { 
    } 
} 

使い方(XML):

<android.util.SwitchPreference 
    android:key="whatever" 
    android:title="Whatever" /> 

使用方法(Javaの):

SwitchPreference switchPreference = (SwitchPreference) findPreference("whatever"); 
switchPreference.setOnPreferenceClickListener(new OnPreferenceClickListener() { 
    @Override 
    public boolean onPreferenceClick(Preference preference) { 
     DialogUtils.showToast(Preferences.this, "Clicked outside switch"); 
     return true; 
    } 
}); 
switchPreference.setOnPreferenceChangeListener(new OnPreferenceChangeListener() { 
    @Override 
    public boolean onPreferenceChange(Preference preference, Object newValue) { 
     DialogUtils.showToast(Preferences.this, "Clicked inside switch and setting changed"); 
     return true; 
    } 
}); 
+0

私はその良い簡単な答えが好きですが、私はこのコードを試したときに、スイッチの部分をクリックしても、「クリックされた内部スイッチと設定が変更されました」という分岐は取られませんでした。 – Marc

+0

lollipukでは動作しません。 –

1

私はこの1つを試して与え、少し苦労しました。私は私の経験を分かち合うと思った。

最初に私は最大の票を持っていたので、XGouchetで答えを試しました。このソリューションはかなり複雑で、preference headersを使用する必要がありましたが、これは非常にクールですが、私がやっていることに合わないものでした。私がやるべき最も簡単なことは、私のpreferenceFragmentを通常の断片にまとめて、通常のビューでスイッチの設定を偽装することだと決めました。私は好みのためのアンドロイドのソースを掘っおよび上部にこの

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
xmlns:tools="http://schemas.android.com/tools" 
android:layout_width="match_parent" 
android:layout_height="match_parent" 
android:orientation="vertical" 
tools:context="com.lezyne.link.ui.homeScreen.settingsTab.SettingsFragment"> 

<FrameLayout 
    android:id="@+id/fragment_container" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:layout_gravity="center_horizontal"> 


</FrameLayout> 

<View 
    android:layout_width="fill_parent" 
    android:layout_height="1dp" 
    android:layout_marginLeft="15dp" 
    android:layout_marginRight="15dp" 
    android:background="#e1e1e1" /> 

<LinearLayout 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:background="?android:attr/selectableItemBackground" 
    android:gravity="center_vertical" 
    android:minHeight="?android:attr/listPreferredItemHeight" 
    android:orientation="horizontal" 
    android:paddingRight="?android:attr/scrollbarSize"> 

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

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

     <TextView 
      android:id="@+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/textAppearanceLarge" /> 

     <TextView 
      android:id="@+id/summary" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:layout_alignLeft="@android:id/title" 
      android:layout_below="@android:id/title" 
      android:maxLines="4" 
      android:textAppearance="?android:attr/textAppearanceSmall" 
      android:textColor="?android:attr/textColorSecondary" /> 

    </RelativeLayout> 

    <!-- Preference should place its actual preference widget here. --> 
    <RelativeLayout 
     android:id="@+id/widget_frame" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:gravity="center_vertical" 
     android:orientation="vertical" 
     android:paddingEnd="36dp"> 


     <Switch 
      android:thumb="@drawable/switch_inner" 
      android:id="@+id/switch1" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:layout_alignParentEnd="true" /> 

     <TextView 
      android:id="@+id/textView6" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:layout_marginLeft="2dp" 
      android:text="@string/Notifications" 
      android:textAppearance="?android:attr/textAppearanceMedium" /> 

    </RelativeLayout> 

</LinearLayout> 


<View 
    android:layout_width="fill_parent" 
    android:layout_height="1dp" 
    android:layout_marginLeft="15dp" 
    android:layout_marginRight="15dp" 
    android:background="#e1e1e1" /> 


</LinearLayout> 

でframeLayoutを思い付いたので

getChildFragmentManager() 
      .beginTransaction() 
      .replace(R.id.fragment_container, new SettingsPreferencesFragment(), "SettingsPreferencesFragment") 
      .commit(); 

のような好みのフラグメントを取得しますそれから私は、私と同じように私のクリックリスナーを割り当てる得ることができます定期的な視点でSettingsPreferencesFragmentは完全に標準的な嗜好フラグメントです。

このソリューションはかなり良さそうでしたが、その後、私はタブレットで奇妙なレイアウトの問題に気付きました。私は、このソリューションをすべてのデバイスで正しく見せるのに問題があり、実際のswitchPreferenceを偽のものではなく使用する必要があることに気付きました。

==============ソリューション2 ===============

AlikElzin-kilaka's solutionがいいとシンプルでしたが、うまくいきませんでした私が試したとき。私はそれが間違っていないことを確認するために2回目を試みました。私は遊び続けて、うまくいくようなものを思いついた。彼は良い点を持っています

2質問はここにあります:1. スイッチエリア外をクリックしてください。 2.アクションバーにスイッチを入れる方法は?

本当に唯一の問題質問2私は好みでビューへのアクセスを取得する唯一の方法は、子クラスとオーバーライドを作成することに気づいたhereother places

に答えてきたので、(1)答える価値がありますonBind。だから私はSwitchPreferenceのこの子クラスを思いついて、スイッチのために別々のクリックハンドラをビュー全体として作成します。それはまだハックだ。

public class MySwitchPreference extends SwitchPreference { 
public MySwitchPreference(Context context, AttributeSet attrs, int defStyleAttr) { 
    super(context, attrs, defStyleAttr); 
} 


public MySwitchPreference(Context context, AttributeSet attrs) { 
    super(context, attrs); 
    getView(null,null); 

} 

public MySwitchPreference(Context context) { 
    super(context); 
} 

public interface SwitchClickListener{ 
    public void onSwitchClicked(boolean checked); 
    public void onPreferenceClicked(); 
} 
private SwitchClickListener listener = null; 
public void setSwitchClickListener(SwitchClickListener listener){ 
    this.listener = listener; 
} 

public Switch findSwitchWidget(View view){ 
    if (view instanceof Switch){ 
     return (Switch)view; 
    } 
    if (view instanceof ViewGroup){ 
     ViewGroup viewGroup = (ViewGroup)view; 
     for (int i = 0; i < viewGroup.getChildCount();i++){ 
      View child = viewGroup.getChildAt(i); 
      if (child instanceof ViewGroup){ 
       Switch result = findSwitchWidget(child); 
       if (result!=null) return result; 
      } 
      if (child instanceof Switch){ 
       return (Switch)child; 
      } 
     } 
    } 
    return null; 
} 

protected void onBindView (View view){ 
    super.onBindView(view); 

    final Switch switchView = findSwitchWidget(view); 
    if (switchView!=null){ 
     switchView.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       if (listener!=null) listener.onSwitchClicked(switchView.isChecked()); 
      } 
     }); 
     switchView.setFocusable(true); 
     switchView.setEnabled(true); 
    } 

    view.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      if (listener!=null) listener.onPreferenceClicked(); 
     } 
    }); 

} 
} 

スイッチを見つけるまで再帰関数findSwitchWidgetを使用してツリーを移動します。

Switch switchView = view.findViewById(android.R.id.switchView); 

を私が知っているその内部id値を取得する方法があるように思えません。私はむしろ、このようなコードを記述しているだろう。いずれにしても、実際のスイッチがあれば、リスナーとコンテナビューを割り当てることができます。スイッチの設定は自動的に更新されないため、設定を自分で保存する必要があります。

MySwitchPreference switchPreference = (MySwitchPreference) findPreference("whatever"); 
    switchPreference.setSwitchClickListener(new MySwitchPreference.SwitchClickListener() { 
     @Override 
     public void onSwitchClicked(boolean checked) { 
      //Save the preference value here 
     } 

     @Override 
     public void onPreferenceClicked() { 
      //Launch the new preference screen or activity here 
     } 
    }); 

うまくいけば、この第2のハックは私をかむために戻らないことを望みます。

この方法の潜在的な落とし穴はありますか?

また、私はgithubのあなたのXMLがどのように見えるかhttps://gist.github.com/marchold/45e22839eb94aa14dfb5

関連する問題