如何在Preference中添加“长按监听器”?

8

我有一个PreferenceActivity,我想动态添加偏好设置。

长按这些设置应该会触发一些操作,但是OnPreferenceClickListener只支持普通点击,不支持长按。

有没有办法实现这个功能,我错过了什么吗?

谢谢。

2个回答

13

如果链接失效,这里是该链接中的主要内容。注意:以下内容非本人原创。

内置的Preference类有一个接收点击事件的方法onClick,但没有接收长按的方法。在我的当前项目中,我确实需要这个功能,并找到了一种实现方式。

PreferenceActivity实际上是一个ListActivity,其后面有一个特殊的适配器。通常(不是长按)的点击是通过使用常规的ListView机制setOnItemClickListener来处理的。设置此项的代码在PreferenceScreen中:

public final class PreferenceScreen extends PreferenceGroup implements AdapterView.OnItemClickListener.... {
    public void bind(ListView listView) {
        listView.setOnItemClickListener(this);
        listView.setAdapter(getRootAdapter());

        onAttachedToActivity();
    }

    public void onItemClick(AdapterView parent, View view, int position, long id) {
        Object item = getRootAdapter().getItem(position);
        if (!(item instanceof Preference)) return;
                     
        final Preference preference = (Preference) item;
        preference.performClick(this);
    }
}

如果PreferenceScreen可以被子类化并重写绑定方法以向列表视图添加长按项单击侦听器,那将非常容易,但是这个类是final的。因此,我最终在我的PreferenceActivity子类中添加了以下代码:

public class BlahBlahActivity extends PreferenceActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
 
        addPreferencesFromResource(R.xml.account_options_prefs);
 
        ListView listView = getListView();
        listView.setOnItemLongClickListener(new OnItemLongClickListener() {
            @Override
            public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
                ListView listView = (ListView) parent;
                ListAdapter listAdapter = listView.getAdapter();
                Object obj = listAdapter.getItem(position);
                if (obj != null && obj instanceof View.OnLongClickListener) {
                    View.OnLongClickListener longListener = (View.OnLongClickListener) obj;
                    return longListener.onLongClick(view);
                }
                return false;
            }
        });
    }
}

现在我可以拥有一个Preference子类,该子类实现了View.OnLongClickListener接口,自动处理长按事件:

public class BlahBlahPreference extends CheckBoxPreference implements View.OnLongClickListener {
    @Override
    public boolean onLongClick(View v) {
        // Do something for long click
        return true;
    }
}

我怎么知道哪个偏好设置被长按了? - android developer
@androiddeveloper 从列表适配器中获取的项(请注意 onItemLongClick 方法)是 Preference 类型,只需调用 getKey() 方法即可获取键。 - grine4ka
@grine4ka 这是一个相当古老的帖子,但现在我读了一下,我发现你所说的函数并没有任何首选类。Preference 不扩展 View... 它只得到了 "AdapterView<?> parent, View view, int position, long id"。 - android developer
@androiddeveloper ListView listView = (ListView) parent; ListAdapter listAdapter = listView.getAdapter(); Object obj = listAdapter.getItem(position); obj的类型是Preference或其子类之一。 - grine4ka
似乎PreferenceFragment中没有此函数可用。但是,在onCreateView中可以使用findViewById(android.R.id.list)找到ListView。是否有更好的方法? - android developer

1

目前无法为您进行测试,但我想知道您是否可以通过在Preference上使用getView()方法来实现此目的。然后,一旦您获得了该View,请使用setOnLongClickListener()


我尝试使用CheckboxPreference,但只有一半起作用。首选项可以长按,但复选框变为不可点击,我无法弄清楚如何修复它。 - Mark
@Mark...尝试在onLongClick()回调中返回false。 - Zain

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接