2012-03-16 7 views
11

जो मैं कार्यान्वित करने की कोशिश कर रहा हूं वह नीचे दी गई छवि की मूल रूप से और सटीक प्रतिकृति है (प्राथमिकताएं जिन्हें मैंने स्क्वायर किया है)। वरीयता के बाईं ओर कुछ भी दबाकर एक संवाद खोलना चाहिए। टॉगलबटन दबाकर जो भी मैं इस वरीयता में सेट कर रहा हूं उसे अक्षम/सक्षम कर दूंगा।मैं एडिटटेक्स्ट प्रेफरेंस और टॉगलबटन के साथ एक वरीयता कैसे बना सकता हूं?

मैं अब घंटों की कोशिश कर रहा हूं और मैं खाली हाथ आया हूं। मैं वरीयता सक्रियता में इसे कैसे कार्यान्वित करूं?

Preference

संपादित करें: ऐसा लगता है लोग मेरे सवाल का गलत समझ रहे हैं। यह बहुत महत्वपूर्ण है कि मैं वरीयता निष्पादन का उपयोग करके अपनी समस्या को हल करने का तरीका समझता हूं। एक गतिविधि नहीं मुझे परवाह नहीं है कि मुझे इसे एक्सएमएल या प्रोग्रामेटिक रूप से करने की ज़रूरत है या नहीं। बस मुझे जवाब देने से बचना चाहिए कि मैं एक या कुछ समान के भीतर उपयोग नहीं कर सकता।

संपादित करें 2: एक इनाम जोड़ा गया - मैं वास्तव में इस

+0

खुशी है कि आप इस सूत्र शुरू कर दिया था! :) – Roylee

उत्तर

17

नरक आदमी, मैं अपने विचार :-)

यह बस के रूप में एक ही @ एमएच का जवाब है, लेकिन अधिक संक्षिप्त है की तरह है।

मैंने ToggleButton के साथ परीक्षण किया, Switch नहीं।

package android.dumdum; 

import android.content.Context; 
import android.preference.Preference; 
import android.util.AttributeSet; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.LinearLayout; 
import android.widget.TextView; 
import android.widget.ToggleButton; 

public class TogglePreference extends Preference { 

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

    public TogglePreference(Context context, AttributeSet attrs) { 
     super(context, attrs); 
    } 

    public TogglePreference(Context context, AttributeSet attrs, int defStyle) { 
     super(context, attrs, defStyle); 
    } 

    public View getView(View convertView, ViewGroup parent) { 
     if (convertView == null) { 
      convertView = new LinearLayout(getContext()); 
      ((LinearLayout) convertView) 
        .setOrientation(LinearLayout.HORIZONTAL); 

      TextView txtInfo = new TextView(getContext()); 

      txtInfo.setText("Test"); 
      ((LinearLayout) convertView).addView(txtInfo, 
        new LinearLayout.LayoutParams(
          LinearLayout.LayoutParams.MATCH_PARENT, 
          LinearLayout.LayoutParams.WRAP_CONTENT, 1)); 

      ToggleButton btn = new ToggleButton(getContext()); 
      ((LinearLayout) convertView).addView(btn); 
     } 

     return convertView; 
    } 
} 

और preferences.xml:

<?xml version="1.0" encoding="utf-8"?> 
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" > 

    <PreferenceCategory android:title="Test custom preferences" > 
     <android.dumdum.EncryptorEditTextPreference /> 
     <android.dumdum.TogglePreference /> 
    </PreferenceCategory> 

</PreferenceScreen> 

EncryptorEditTextPreference आपके प्रश्न से संबंधित नहीं है, लेकिन यह एक ही तकनीक (EditTextPreference विस्तार) का उपयोग करता है।

0

है कि यदि एक टॉगल बटन है कुछ नहीं करने के लिए एक जवाब की जरूरत है लेकिन अगर यह है तो आप सिर्फ एंड्रॉयड कह सकते हैं: textOn या एंड्रॉयड: पर textoff। एक्सएमएल। यदि यह जावा भाग पर है तो शायद यह सेटटाक्स्टऑनॉट की तरह कुछ निश्चित नहीं है अगर यह टॉगल बटन है, लेकिन यदि यह है तो आप केवल एंड्रॉइड कह सकते हैं: textOn या android: .xml पर textoff। यदि यह जावा भाग पर है तो शायद यह टॉगल बटन जैसे कुछ है।

0

मुझे यकीन है कि समस्या क्या आप में, मैं सिर्फ तुम क्या बात कर रहे हैं की तरह एक डमी दृश्य निर्मित भाग गया नहीं हूँ और मैं किसी भी समस्या

<TableRow 
    android:id="@+id/tableRow1" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" > 

    <TextView 
     android:id="@+id/textView1" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:text="Large Text" 
     android:textAppearance="?android:attr/textAppearanceLarge" /> 


    <Switch 
     android:id="@+id/switch1" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_gravity="right" 
     android:text="Switch" /> 

</TableRow> 
+0

जिन समस्याओं में मैं चल रहा हूं वे तथ्य हैं कि मैं वरीयता सक्रियता में काम कर रहा हूं। एक गतिविधि नहीं वरीयता सक्रियता इस तरह से अलग-अलग काम करती है कि प्रत्येक "पंक्ति" को एक्सएमएल में प्रीफरेंसेटैग द्वारा परिभाषित किया गया है: या । मेरी समस्या इन दो प्राथमिकताओं के संयोजन के साथ है। एक टैबलेरो में सिर्फ एक स्विच और एक टेक्स्टव्यू नहीं बना रहा है। – CodePrimate

0

आप अपने वरी में इस एक्सएमएल कोड का उपयोग कर सकते नहीं दिख रहा है xml फ़ाइल

<PreferenceCategory> 
     <EditTextPreference 
      android:key="myEditText" 
      android:title="Hi" 
      android:inputType="Mine"></EditTextPreference> 
    </PreferenceCategory> 

और आप के बजाय इस कोड के साथ ToggleButton एक चेकबॉक्स का उपयोग कर सकते हैं:

<CheckBoxPreference 
     android:key="testmode" 
     android:title="@string/test_mode"></CheckBoxPreference> 

अगर क्या आप इस कोड का उपयोग कर सकते हैं चेकबॉक्स का उपयोग नहीं करना चाहते हैं:

+1

धन्यवाद, आपका कोड काफी अच्छा है :-) –

8

बस एक नोट अग्रिम: यह एक लंबी जवाब का एक सा होने जा रहा है, लेकिन मेरा इरादा प्रदान करना है आप एक अच्छा जवाब देने के साथ कि आप सचमुच शुरू करने के लिए कॉपी और पेस्ट कर सकते हैं।

यह वास्तव में पूरा करने में बहुत मुश्किल नहीं है। आपका सबसे अच्छा प्रारंभिक बिंदु आईसीएस पर SwichPreference के कार्यान्वयन को देखना होगा। आप देखेंगे कि यह काफी सरल है, अधिकांश काम TwoStatePreference सुपरक्लास द्वारा किया जा रहा है, जो इसकी बारी पर केवल आईसीएस उपलब्ध है। सौभाग्य से, आप लगभग SwitchPreference कार्यान्वयन के रूप में कार्यान्वयन के उपयोग से, उस वर्ग के लगभग TogglePreference (चलिए इसे स्पष्टता के लिए कहते हैं) के आधार पर लगभग सचमुच कॉपी-पेस्ट (इस उत्तर में सभी तरह से नीचे देखें) बना सकते हैं।

आपको ऐसा करने से क्या मिलेगा, नीचे कुछ ऐसा है। मैंने प्रत्येक विधि को कुछ स्पष्टीकरण जोड़ा ताकि मैं यहां अपने लेखन को सीमित कर सकूं।

TogglePreference।जावा

package mh.so.pref; 

import mh.so.R; 
import android.content.Context; 
import android.preference.Preference; 
import android.util.AttributeSet; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.CompoundButton; 
import android.widget.ToggleButton; 

/** 
* A {@link Preference} that provides a two-state toggleable option. 
* <p> 
* This preference will store a boolean into the SharedPreferences. 
*/ 
public class TogglePreference extends TwoStatePreference { 
    private final Listener mListener = new Listener(); 
    private ExternalListener mExternalListener; 

    /** 
    * Construct a new TogglePreference with the given style options. 
    * 
    * @param context The Context that will style this preference 
    * @param attrs Style attributes that differ from the default 
    * @param defStyle Theme attribute defining the default style options 
    */ 
    public TogglePreference(Context context, AttributeSet attrs, int defStyle) { 
     super(context, attrs, defStyle); 
    } 

    /** 
    * Construct a new TogglePreference with the given style options. 
    * 
    * @param context The Context that will style this preference 
    * @param attrs Style attributes that differ from the default 
    */ 
    public TogglePreference(Context context, AttributeSet attrs) { 
     super(context, attrs); 
    } 

    /** 
    * Construct a new TogglePreference with default style options. 
    * 
    * @param context The Context that will style this preference 
    */ 
    public TogglePreference(Context context) { 
     this(context, null); 
    } 

    /** Inflates a custom layout for this preference, taking advantage of views with ids that are already 
    * being used in the Preference base class. 
    */ 
    @Override protected View onCreateView(ViewGroup parent) { 
     LayoutInflater inflater = (LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
     return inflater.inflate(R.layout.toggle_preference_layout, parent, false); 
    } 

    /** Since the Preference base class handles the icon and summary (or summaryOn and summaryOff in TwoStatePreference) 
    * we only need to handle the ToggleButton here. Simply get it from the previously created layout, set the data 
    * against it and hook up a listener to handle user interaction with the button. 
    */ 
    @Override protected void onBindView(View view) { 
     super.onBindView(view); 

     ToggleButton toggleButton = (ToggleButton) view.findViewById(R.id.toggle_togglebutton); 
     toggleButton.setChecked(isChecked()); 
     toggleButton.setOnCheckedChangeListener(mListener); 
    } 

    /** This gets called when the preference (as a whole) is selected by the user. The TwoStatePreference 
    * implementation changes the actual state of this preference, which we don't want, since we're handling 
    * preference clicks with our 'external' listener. Hence, don't call super.onClick(), but the onPreferenceClick 
    * of our listener. */ 
    @Override protected void onClick() { 
     if (mExternalListener != null) mExternalListener.onPreferenceClick(); 
    } 

    /** Simple interface that defines an external listener that can be notified when the preference has been 
    * been clicked. This may be useful e.g. to navigate to a new activity from your PreferenceActivity, or 
    * display a dialog. */ 
    public static interface ExternalListener { 
     void onPreferenceClick(); 
    } 

    /** Sets an external listener for this preference*/ 
    public void setExternalListener(ExternalListener listener) { 
     mExternalListener = listener; 
    } 

    /** Listener to update the boolean flag that gets stored into the Shared Preferences */ 
    private class Listener implements CompoundButton.OnCheckedChangeListener { 
     @Override 
     public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 
      if (!callChangeListener(isChecked)) { 
       // Listener didn't like it, change it back. 
       // CompoundButton will make sure we don't recurse. 
       buttonView.setChecked(!isChecked); 
       return; 
      } 

      TogglePreference.this.setChecked(isChecked); 
     } 
    } 

} 

इस उदाहरण के लिए लेआउट फ़ाइल बस एक उस में LinearLayout तीन के साथ तत्वों, सबसे दिलचस्प एक होने ToggleButton के साथ है। ImageView और TextViewPreference बेस क्लास का लाभ उठाएं जो एंड्रॉइड नेमस्पेस में उपयुक्त आईडी का उपयोग करके पहले से ही करता है। इस तरह, हमें उन लोगों के बारे में चिंता करने की ज़रूरत नहीं है। ध्यान दें कि मुझे पूरा यकीन है कि आइकन विकल्प हनीकॉम तक नहीं जोड़ा गया था, इसलिए आप इसे TogglePreference पर एक कस्टम विशेषता के रूप में जोड़ना चाहते हैं और इसे मैन्युअल रूप से सेट करना चाहते हैं ताकि यह हमेशा वहां रहे। अगर आपको इस दृष्टिकोण के लिए और अधिक ठोस पॉइंटर्स की आवश्यकता है तो बस मुझे एक टिप्पणी फ्लिक करें।

वैसे भी, आप किसी भी विस्तार के लिए लेआउट को संशोधित कर सकते हैं, और अपनी पसंद के अनुसार स्टाइल लागू कर सकते हैं। उदाहरण के लिए, ToggleButtonSwitch नकल करने के लिए, आप पृष्ठभूमि को किसी अन्य StateListDrawable पर बदल सकते हैं और/या बदल सकते हैं या पूरी तरह से चालू/बंद टेक्स्ट से छुटकारा पा सकते हैं।

toggle_preference_layout.xml

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent" 
    android:layout_height="?android:attr/listPreferredItemHeight" > 

    <ImageView 
     android:id="@android:id/icon" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_gravity="center_vertical" 
     android:focusable="false" 
     android:focusableInTouchMode="false" /> 

    <TextView 
     android:id="@android:id/summary" 
     android:layout_width="0dp" 
     android:layout_height="wrap_content" 
     android:layout_gravity="center_vertical" 
     android:layout_weight="1" 
     android:focusable="false" 
     android:focusableInTouchMode="false" 
     android:textAppearance="?android:attr/textAppearanceMedium" /> 

    <ToggleButton 
     android:id="@+id/toggle_togglebutton" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_gravity="center_vertical" 
     android:focusable="false" 
     android:focusableInTouchMode="false" /> 

</LinearLayout> 

फिर आप सिर्फ अपने PreferenceActivity में किसी भी अन्य की तरह PreferenceTogglePreference उपयोग कर सकते हैं। श्रोता को जोड़कर, जब आप उपयोगकर्ता को वरीयता चुनते हैं तो आप कुछ भी कर सकते हैं, जबकि एक ही समय में वास्तविक ToggleButton पर क्लिक करके SharedPreferences में बूलियन मान टॉगल करेगा।

DemoPreferenceActivity.java

package mh.so.pref; 

import mh.so.R; 
import android.os.Bundle; 
import android.preference.PreferenceActivity; 
import android.widget.Toast; 

public class DemoPreferenceActivity extends PreferenceActivity { 

    @Override protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     addPreferencesFromResource(R.xml.prefs); 

     TogglePreference toggle = (TogglePreference) findPreference("toggle_preference"); 
     toggle.setExternalListener(new TogglePreference.ExternalListener() { 
      @Override public void onPreferenceClick() { 
       Toast.makeText(DemoPreferenceActivity.this, "You clicked the preference without changing its value", Toast.LENGTH_LONG).show(); 
      } 
     }); 
    } 

} 

Prefs.xml ज्यादा कुछ नहीं लेकिन TogglePreference ऊपर की एक एकल परिभाषा है। आप एंड्रॉइड के नामस्थान में सभी सामान्य विशेषताओं की आपूर्ति कर सकते हैं। वैकल्पिक रूप से आप summaryOn और summaryOff ग्रंथों से निपटने के लिए TwoStatePreference की अंतर्निहित कार्यक्षमता का शोषण करने के लिए कुछ कस्टम विशेषताओं की घोषणा भी कर सकते हैं।

Prefs.xml

<?xml version="1.0" encoding="utf-8"?> 
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" > 

    <PreferenceCategory android:title="Toggle preferences" > 
     <mh.so.pref.TogglePreference xmlns:app="http://schemas.android.com/apk/res/mh.so" 
      android:key="toggle_preference" 
      android:summary="Summary" 
      android:icon="@drawable/icon" /> 
    </PreferenceCategory> 

</PreferenceScreen> 

अंत में, आईसीएस से बैकपोर्टेड TwoStatePreference वर्ग। यह मूल रूप से मूल से अलग नहीं है, जिसके लिए आप स्रोत overhere पा सकते हैं।

package mh.so.pref; 

import android.content.Context; 
import android.content.SharedPreferences; 
import android.content.res.TypedArray; 
import android.os.Parcel; 
import android.os.Parcelable; 
import android.preference.Preference; 
import android.util.AttributeSet; 
import android.view.View; 
import android.widget.TextView; 

/** 
* Common base class for preferences that have two selectable states, persist a 
* boolean value in SharedPreferences, and may have dependent preferences that are 
* enabled/disabled based on the current state. 
*/ 
public abstract class TwoStatePreference extends Preference { 

    private CharSequence mSummaryOn; 
    private CharSequence mSummaryOff; 
    private boolean mChecked; 
    private boolean mDisableDependentsState; 


    public TwoStatePreference(Context context, AttributeSet attrs, int defStyle) { 
     super(context, attrs, defStyle); 
    } 

    public TwoStatePreference(Context context, AttributeSet attrs) { 
     this(context, attrs, 0); 
    } 

    public TwoStatePreference(Context context) { 
     this(context, null); 
    } 

    @Override 
    protected void onClick() { 
     super.onClick(); 

     boolean newValue = !isChecked(); 

     if (!callChangeListener(newValue)) { 
      return; 
     } 

     setChecked(newValue); 
    } 

    /** 
    * Sets the checked state and saves it to the {@link SharedPreferences}. 
    * 
    * @param checked The checked state. 
    */ 
    public void setChecked(boolean checked) { 
     if (mChecked != checked) { 
      mChecked = checked; 
      persistBoolean(checked); 
      notifyDependencyChange(shouldDisableDependents()); 
      notifyChanged(); 
     } 
    } 

    /** 
    * Returns the checked state. 
    * 
    * @return The checked state. 
    */ 
    public boolean isChecked() { 
     return mChecked; 
    } 

    @Override 
    public boolean shouldDisableDependents() { 
     boolean shouldDisable = mDisableDependentsState ? mChecked : !mChecked; 
     return shouldDisable || super.shouldDisableDependents(); 
    } 

    /** 
    * Sets the summary to be shown when checked. 
    * 
    * @param summary The summary to be shown when checked. 
    */ 
    public void setSummaryOn(CharSequence summary) { 
     mSummaryOn = summary; 
     if (isChecked()) { 
      notifyChanged(); 
     } 
    } 

    /** 
    * @see #setSummaryOn(CharSequence) 
    * @param summaryResId The summary as a resource. 
    */ 
    public void setSummaryOn(int summaryResId) { 
     setSummaryOn(getContext().getString(summaryResId)); 
    } 

    /** 
    * Returns the summary to be shown when checked. 
    * @return The summary. 
    */ 
    public CharSequence getSummaryOn() { 
     return mSummaryOn; 
    } 

    /** 
    * Sets the summary to be shown when unchecked. 
    * 
    * @param summary The summary to be shown when unchecked. 
    */ 
    public void setSummaryOff(CharSequence summary) { 
     mSummaryOff = summary; 
     if (!isChecked()) { 
      notifyChanged(); 
     } 
    } 

    /** 
    * @see #setSummaryOff(CharSequence) 
    * @param summaryResId The summary as a resource. 
    */ 
    public void setSummaryOff(int summaryResId) { 
     setSummaryOff(getContext().getString(summaryResId)); 
    } 

    /** 
    * Returns the summary to be shown when unchecked. 
    * @return The summary. 
    */ 
    public CharSequence getSummaryOff() { 
     return mSummaryOff; 
    } 

    /** 
    * Returns whether dependents are disabled when this preference is on ({@code true}) 
    * or when this preference is off ({@code false}). 
    * 
    * @return Whether dependents are disabled when this preference is on ({@code true}) 
    *   or when this preference is off ({@code false}). 
    */ 
    public boolean getDisableDependentsState() { 
     return mDisableDependentsState; 
    } 

    /** 
    * Sets whether dependents are disabled when this preference is on ({@code true}) 
    * or when this preference is off ({@code false}). 
    * 
    * @param disableDependentsState The preference state that should disable dependents. 
    */ 
    public void setDisableDependentsState(boolean disableDependentsState) { 
     mDisableDependentsState = disableDependentsState; 
    } 

    @Override 
    protected Object onGetDefaultValue(TypedArray a, int index) { 
     return a.getBoolean(index, false); 
    } 

    @Override 
    protected void onSetInitialValue(boolean restoreValue, Object defaultValue) { 
     setChecked(restoreValue ? getPersistedBoolean(mChecked) 
       : (Boolean) defaultValue); 
    } 

    /** 
    * Sync a summary view contained within view's subhierarchy with the correct summary text. 
    * @param view View where a summary should be located 
    */ 
    void syncSummaryView(View view) { 
     // Sync the summary view 
     TextView summaryView = (TextView) view.findViewById(android.R.id.summary); 
     if (summaryView != null) { 
      boolean useDefaultSummary = true; 
      if (mChecked && mSummaryOn != null) { 
       summaryView.setText(mSummaryOn); 
       useDefaultSummary = false; 
      } else if (!mChecked && mSummaryOff != null) { 
       summaryView.setText(mSummaryOff); 
       useDefaultSummary = false; 
      } 

      if (useDefaultSummary) { 
       final CharSequence summary = getSummary(); 
       if (summary != null) { 
        summaryView.setText(summary); 
        useDefaultSummary = false; 
       } 
      } 

      int newVisibility = View.GONE; 
      if (!useDefaultSummary) { 
       // Someone has written to it 
       newVisibility = View.VISIBLE; 
      } 
      if (newVisibility != summaryView.getVisibility()) { 
       summaryView.setVisibility(newVisibility); 
      } 
     } 
    } 

    @Override 
    protected Parcelable onSaveInstanceState() { 
     final Parcelable superState = super.onSaveInstanceState(); 
     if (isPersistent()) { 
      // No need to save instance state since it's persistent 
      return superState; 
     } 

     final SavedState myState = new SavedState(superState); 
     myState.checked = isChecked(); 
     return myState; 
    } 

    @Override 
    protected void onRestoreInstanceState(Parcelable state) { 
     if (state == null || !state.getClass().equals(SavedState.class)) { 
      // Didn't save state for us in onSaveInstanceState 
      super.onRestoreInstanceState(state); 
      return; 
     } 

     SavedState myState = (SavedState) state; 
     super.onRestoreInstanceState(myState.getSuperState()); 
     setChecked(myState.checked); 
    } 

    static class SavedState extends BaseSavedState { 
     boolean checked; 

     public SavedState(Parcel source) { 
      super(source); 
      checked = source.readInt() == 1; 
     } 

     @Override 
     public void writeToParcel(Parcel dest, int flags) { 
      super.writeToParcel(dest, flags); 
      dest.writeInt(checked ? 1 : 0); 
     } 

     public SavedState(Parcelable superState) { 
      super(superState); 
     } 

     public static final Parcelable.Creator<SavedState> CREATOR = 
       new Parcelable.Creator<SavedState>() { 
      public SavedState createFromParcel(Parcel in) { 
       return new SavedState(in); 
      } 

      public SavedState[] newArray(int size) { 
       return new SavedState[size]; 
      } 
     }; 
    } 
} 

TogglePreference without any fancy styling applied

0

सीधे शब्दों में SwitchPreference

का उपयोग

<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" > <SwitchPreference android:key="test" android:title="This is test toggle switch" /> </PreferenceScreen>

इस तरह दिखता है (सिर्फ एक मेरे ऐप से नमूना, अन्य वरीयता के बारे में परेशान न) enter image description here

संबंधित मुद्दे