Here是一个类似的问题,但假设使用
PreferenceActivity
。
但是,当没有
PreferenceActivity
时,例如使用 PreferenceFragment
时,如何使首选项可长按?
PreferenceFragment
不提供对 ListView
的引用(getListView()
在 API 中隐藏),因此无法采用相同的方法。
class LongClickablePreference(context: Context, attrs: AttributeSet?) : Preference(context, attrs) {
/**
* @return true if the long-click was handled
*/
var onPreferenceLongClickListener: ((Preference) -> Boolean)? = null
override fun onBindViewHolder(holder: PreferenceViewHolder) {
super.onBindViewHolder(holder)
holder.itemView.setOnLongClickListener {
performLongClick()
}
}
private fun performLongClick(): Boolean {
if (!isEnabled || !isSelectable) {
return false
}
return onPreferenceLongClickListener?.invoke(this) ?: false
}
}
对于其他
Preference
类型可以采取类似的方法。
我在上面找到的所有答案现在都已经过时了,因为它们处理基于 ListView 的首选项屏幕,而 AppCmpat 和 androidx 使用 RecyclerView。在这种情况下,可以执行以下操作: 1. 扩大优惠等级 2. 重写onBindViewHolder 3. 为外部fragment/activity定义一些接口并调用Holder.View.OnLongClickListener中的接口方法
private static class OrgPreference extends SwitchPreference
{
private final OnEntryClickListener mOnEntryClickListener;
public OrgPreference(Context context, OnEntryClickListener onEntryClickListener) {
super(context);
mOnEntryClickListener = onEntryClickListener;
}
@Override
public void onBindViewHolder(PreferenceViewHolder holder) {
super.onBindViewHolder(holder);
holder.itemView.setOnLongClickListener(view -> {
String companyId = OrgPreference.this.getKey();
mOnEntryClickListener.onEntryLongClick(companyId);
return true;
});
}
}
在片段/活动中:
interface OnEntryClickListener {
void onEntryLongClick(String companyId);
}
...
OrgPreference switchPreference = new OrgPreference(getContext(), new OnEntryClickListener() {
@Override
public void onEntryLongClick(String companyId) {
//Do stuff
}
});
在迁移旧的(Froyo)应用程序时,我为这个挑战奋斗了 2-3 天(在
ListPreference
中制作 AndroidX PreferenceFragment
可长时间点击)。我不明白为什么,尽管遵循了此处和这篇博文中提供的解决方案,但我无法使长按起作用。问题之一是 ListPreference
不直接继承于 View
并且没有 setOnLongClickListener
。
然后我求助于创建一个专用应用程序,仅仅是为了使这项工作顺利进行。我成功了,但请注意:长按对“选择一个选项”菜单项(显示选项)进行操作,而不是对其中一个选项项进行操作(即“选项一”、“选项二”等)。 这里是完整的工作代码,对于像我这样困惑的人来说是有好处的:
1.清单文件(AndroidManifest.xml):
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.preferencesdemo">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.PreferencesDemo">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
2.主要活动(MainActivity.java):
package com.example.preferencesdemo;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState == null) {
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.settings_container, new SettingsFragment())
.commit();
}
}
}
3.重写自定义首选项类中的 onBindViewHolder。
package com.example.preferencesdemo;
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.widget.Toast;
import androidx.preference.ListPreference;
import androidx.preference.PreferenceViewHolder;
public class LongPressListPreference extends ListPreference {
public LongPressListPreference(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public void onBindViewHolder(PreferenceViewHolder holder) {
super.onBindViewHolder(holder);
holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
CharSequence currentEntry = getEntry();
Toast.makeText(getContext(),
"Long pressed: " + currentEntry,
Toast.LENGTH_SHORT).show();
return true;
}
});
}
}
4.设置片段(SettingsFragment.java):
package com.example.preferencesdemo;
import android.os.Bundle;
import androidx.preference.PreferenceFragmentCompat;
public class SettingsFragment extends PreferenceFragmentCompat {
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
setPreferencesFromResource(R.xml.usersettings, rootKey);
}
}
5.使用此自定义首选项的 usersettings.xml
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<com.example.preferencesdemo.LongPressListPreference
android:key="list_preference_key"
android:title="@string/list_preference_title"
android:summary="@string/list_preference_summary"
android:entries="@array/list_preference_entries"
android:entryValues="@array/list_preference_entry_values"
android:defaultValue="option1" />
</PreferenceScreen>
6.主布局(res/layout/activity_main.xml):
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/settings_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
7.字符串资源文件(res/values/strings.xml):
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">Preferences Demo</string>
<string name="list_preference_title">Choose an Option</string>
<string name="list_preference_summary">Long press to show toast</string>
<string-array name="list_preference_entries">
<item>Option One</item>
<item>Option Two</item>
<item>Option Three</item>
<item>Option Four</item>
<item>Option Five</item>
</string-array>
<string-array name="list_preference_entry_values">
<item>option1</item>
<item>option2</item>
<item>option3</item>
<item>option4</item>
<item>option5</item>
</string-array>
</resources>
8. build.gradle(应用程序级别):
plugins {
id 'com.android.application'
}
android {
compileSdk 34
defaultConfig {
applicationId "com.example.preferencesdemo"
minSdk 26
targetSdk 34
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_17
targetCompatibility JavaVersion.VERSION_17
}
}
dependencies {
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'androidx.preference:preference:1.2.1'
}