【问题标题】:Android adding event to a CustomPreference element (TextView)Android将事件添加到CustomPreference元素(TextView)
【发布时间】:2015-03-01 17:50:17
【问题描述】:

我正在使用带有两个片段的 PreferenceActivity,每个片段都包含一个 PreferenceScreen。

我想做的是在我拥有的自定义首选项上创建一个事件侦听器(此自定义首选项的一行是带有 SwitchView 的 TextView)。我很好地处理了 Switch 首选项,它可以根据需要保存它,但现在我想做的是在 SwitchView 之间的 TextView 上添加一个事件,以在屏幕的另一部分(第二个片段)显示我想要的内容。

让我向您展示我当前的代码。 这是我的 CustomPreference(它只是一个 TextView 和一个 Switch)

public class ItemPreference extends Preference{

private static TextView text;   // this is the text at the left of the switch, it's where i want to handle the event 
                                // to show an other preferencescreen in the fragment between
private Switch switcher;        // the key of the preference is for the SWITCH !!
private boolean checked;
private Context context;

public TextView getCustomText(){
    return text;
}

public ItemPreference(Context context, AttributeSet attrs) {
    super(context, attrs);

    this.context = context;     
    setLayoutResource(R.layout.row_setting);  // the layout resource of my custom preference
}


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

    text = (TextView)view.findViewById(R.id.buttonRowSetting);

    // to display the text in the TextView between the Switch, I use the key of the Switch
    if (this.getKey().equals("pref_key_classification"))        
        text.setText(R.string.title_activity_classification);

    // the switchview and it's preference saving
    switcher = (Switch)view.findViewById(R.id.switchRowSetting);
    Boolean value = this.getPersistedBoolean(false);
    if (value){
        switcher.setChecked(true);
    } else {
        switcher.setChecked(false);
    }

    switcher.setOnCheckedChangeListener(new OnCheckedChangeListener(){
        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            setSwitchChecked(isChecked);
        }
    });
}

public void setSwitchChecked(boolean value) {
    if (checked != value) {
        checked = value;
        persistBoolean(value);
        notifyDependencyChange(shouldDisableDependents());
        notifyChanged();
    }
}

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

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

@Override
protected void onSetInitialValue(boolean restorePersistedValue, Object defaultValue) {
    setSwitchChecked(restorePersistedValue ? getPersistedBoolean(checked) : (Boolean) defaultValue);
}

@Override
protected Parcelable onSaveInstanceState() {
    return super.onSaveInstanceState();
}

@Override
protected void onRestoreInstanceState(Parcelable state) {
    super.onRestoreInstanceState(state);
}   
}

这是 SettingsFragment,位于屏幕左侧,我要在其中处理事件以在屏幕的另一部分显示我想要的内容。

public class SettingsFragment extends PreferenceFragment {

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

    addPreferencesFromResource(R.xml.settings);     // the left preferencefragment 

    Preference stat = (Preference) findPreference(getString(R.string.pref_key_statistic));
    stat.setOnPreferenceClickListener(new OnPreferenceClickListener() {
                 public boolean onPreferenceClick(Preference preference) {                       
                     if(getActivity() instanceof OnSettingPageListener){
                      // if i click on this preference, this loads this preferencescreen on the other fragment, works well.
                        ((OnSettingPageListener)getActivity()).onSettingPageChange(R.xml.settings_stat);
                     }
                     return true;
                 }
             });

    // this is the custompreference, i would like to handle here a listener on the TextView to display a specific preferencescreen on the other fragment
    ItemPreference classif = (ItemPreference) findPreference(getString(R.string.pref_key_classification));  

    // i tried this, and i also tried to make my own Listener also, but doesn't works
    classif.getCustomText().setOnClickListener(new OnClickListener() {          
        @Override
        public void onClick(View v) {
            if (getActivity() instanceof OnSettingPageListener){
            // the content i want to load on the other fragment
                ((OnSettingPageListener)getActivity()).onSettingPageChange(R.xml.settings_classification);
            }               
        }
    });
}

// [...]
}

所以我希望你明白我的问题是什么,这只是听众的问题。有人有解决方案吗?

【问题讨论】:

  • 不,没明白。你到底想做什么?

标签: android android-fragments listener preferences


【解决方案1】:

我不确定您是否希望您的第一个片段上的事件显示第二个片段(以供进一步编辑),或者您是否希望该事件进行更改可见 em> 到第二个片段。

假设您希望更改对第二个片段可见:

  • 让您的第二个片段使用 onSharedPreferenceChanged 方法实现 SharedPreference.OnSharedPreferenceChangeListener,实现当第一个片段中的首选项更改时您希望发生的事情。

  • 在第二个片段的 onResume 方法中,对 SharedPreferences 对象调用 registerOnSharedPreferenceChangeListener

  • 在第二个片段的 onPause 方法中,在 SharedPreferences 对象上调用 unregisterOnSharedPreferenceChangeListener

现在,如果您想显示第二个片段以在第一个片段中编辑首选项:

  • 为您的偏好设置一个fragment 属性,该属性声明编辑您的偏好的片段类

  • 让你的第一个片段实现PreferenceFragment.OnPreferenceStartFragmentCallback 和方法onPreferenceStartFragment 来实例化你的第二个片段并显示它。单击首选项时,您的 PreferenceActivity 子类将调用此回调。

【讨论】:

    【解决方案2】:

    我终于找到了解决方案,我的问题是在我的自定义首选项的 textview 上处理侦听器的方式。我遵循观察者模式,让它在我自己的听众身上工作。

    在我的片段上,我实例化了我的 CustomSwitchPreference(我刚刚重命名了 ItemPreference 类,你可以在楼上看到 ^^)。我调用了我自己的监听器,之后你会看到代码。

    CustomSwitchPreference classif = (CustomSwitchPreference) 
                    findPreference(getString(R.string.pref_key_classification));
    
    classif.setHandlerListener(new ItemPreferenceTextViewListener() {           
            @Override
            public void onHandle(TextView textView) {
                if (getActivity() instanceof OnSettingPageListener){
                    ((OnSettingPageListener)getActivity())
                            .onSettingPageChange(R.xml.settings_classification);
                }               
            }
        });
    

    我们在 CustomPreference 类中寻找监听器,首先创建一个接口来制作你自己的监听器(你可以将它写在与你正在做的 CustomPreference 类相同的文件中):

    interface ItemPreferenceTextViewListener {
    // the function which is going to be called when we will use our listener
        void onHandle(TextView textView);
    }
    

    然后在 CustomPreference 类中执行以下操作:

    // you can put the interface here if you want to make it visible
    
    public class CustomSwitchPreference extends Preference {
    
    private static TextView text;
    // the key of the preference is for the SWITCH !! this activates or 
    // not the "game" on the mainscreen
    private Switch switcher; 
    private boolean checked;
    
    // ---------------------------------------------------------------------- \\
    // create a listener in your own custom preference
    
    ItemPreferenceTextViewListener itemPreferenceTextViewListener ;
    
    // this is the function to handle the event on the textview of the 
    // custom preference item, creates the listener
    public void setHandlerListener(ItemPreferenceTextViewListener listener) {
        itemPreferenceTextViewListener = listener;
    }
    
    // to make the event happen on a textview 
    // (we will pass the right textview in the onBindView(....) )
    protected void myEventListener(TextView textView)   {
        if(itemPreferenceTextViewListener!=null)
            itemPreferenceTextViewListener.onHandle(textView);
    }
    // ---------------------------------------------------------------------- \\
    
    /**
     * @param context
     * @param attrs
     */
    public CustomSwitchPreference(Context context, AttributeSet attrs) {
        super(context, attrs);
    
        setLayoutResource(R.layout.row_setting);
    }
    
    @Override
    protected void onBindView(View view) {
        super.onBindView(view);
    
        // the TextView at the right of the switch, this one 
        // handles a listener to show the other page preference
        text = (TextView)view.findViewById(R.id.buttonRowSetting); 
        // I called it buttonRowSetting because it will handle an event like a button
    
        // I set the text of this TextView with the 
        // key preference of the related switch
        if (this.getKey().equals("pref_key_classification"))        
            text.setText(R.string.title_activity_classification);
        else if (this.getKey().equals("pref_key_matching"))
            text.setText(R.string.title_activity_matching);
        else if (this.getKey().equals("pref_key_intruder"))
            text.setText(R.string.title_activity_intruder);
        else if (this.getKey().equals("pref_key_semantic"))
            text.setText(R.string.title_activity_semantic);
    
        // AND HERE it's where it happens, simply make a basic listener 
        // on the textview, and inside the onClick method, handle your own 
        // listener, on the TextView you initialized just before)
        text.setOnClickListener(new OnClickListener() {         
            @Override
            public void onClick(View v) {   
                // just call 
                itemPreferenceTextViewListener.onHandle(text);
            }
        });
    
        // ---------------------------------------------------------------------- \\
        // to keep the Switch saved in the preferences 
        switcher = (Switch)view.findViewById(R.id.switchRowSetting);        
        Boolean value = this.getPersistedBoolean(false);
        if (value){
            switcher.setChecked(true);
        } else {
            switcher.setChecked(false);
        }
    
        switcher.setOnCheckedChangeListener(new OnCheckedChangeListener(){
            @Override
            public void onCheckedChanged(CompoundButton buttonView,
                    boolean isChecked) {
                setSwitchChecked(isChecked);
            }
        });
        // ---------------------------------------------------------------------- \\
    }
    
    
    public void setSwitchChecked(boolean value) {
        if (checked != value) {
            checked = value;
            persistBoolean(value);
            notifyDependencyChange(shouldDisableDependents());
            notifyChanged();
        }
    }
    
    @Override
    protected Object onGetDefaultValue(TypedArray a, int index) {
        return a.getBoolean(index, false);
    }
    
    @Override
    protected void onClick() {
        super.onClick();
    }
    
    @Override
    protected void onSetInitialValue(boolean restorePersistedValue, 
                                     Object defaultValue) {
        setSwitchChecked(restorePersistedValue 
            ? getPersistedBoolean(checked) : (Boolean) defaultValue);
    }
    
    @Override
    protected Parcelable onSaveInstanceState() {
        return super.onSaveInstanceState();
    }
    
    @Override
    protected void onRestoreInstanceState(Parcelable state) {
        super.onRestoreInstanceState(state);
    }
    }
    

    希望这会有所帮助,这是我的错误,我没有在 myTextView.onClickListener 中调用 onHandle 方法。希望这将有助于更好地理解观察者模式的工作原理。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-10-08
      • 2013-05-04
      • 1970-01-01
      • 1970-01-01
      • 2019-11-13
      • 2013-12-26
      • 1970-01-01
      相关资源
      最近更新 更多