Here is a similar question but assumes the use of PreferenceActivity
.
However, how to make a preference long-clickable when there is no PreferenceActivity
, for example when using a PreferenceFragment
?
PreferenceFragment
does not provide a reference to ListView
( getListView()
is hidden from the API), so the same approach is not possible.
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
}
}
A similar approach can be taken for other Preference
types.
This solution is slightly risky because it makes assumptions about the super class PreferenceFragment (using a ListView and using the android.R.id.list id).
I tried another approach of setting an OnLongClickListener on the pref's View but this then made the checkbox unclickable and I could not find a way to correct that. So this is the best solution i have so far.
public class MyPreferenceFragment extends PreferenceFragment implements OnItemLongClickListener {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
PreferenceScreen root = getPreferenceManager().createPreferenceScreen(getActivity());
setPreferenceScreen(root);
CheckBoxPreference pref = new LongClickableCheckBoxPreference(getActivity()) {
@Override
public boolean onLongClick(View v) {
// YAY! you long-clicked me :)
return true;
}
};
// configure the pref here
root.addPreference(pref);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View result = super.onCreateView(inflater, container, savedInstanceState);
if (result != null) {
View lv = result.findViewById (android.R.id.list);
if (lv instanceof ListView) {
((ListView)lv).setOnItemLongClickListener(this);
}
else {
// oh noes! it looks like this PreferenceFragment does not use the standard id for listviews
}
}
return result;
}
private static abstract class LongClickableCheckBoxPreference extends CheckBoxPreference implements View.OnLongClickListener {
public LongClickableCheckBoxPreference(Context context) {
super(context);
}
}
}
All the answers I found on SO like these above are now obsolete as they deal with preference screen based on ListView whereas AppCmpat and androidx use RecyclerView. In such case one can do the following: 1. Extend preference class 2. Override onBindViewHolder 3. define some interface for outer fragment/activity and invoke interface method in 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;
});
}
}
In fragment/activity:
interface OnEntryClickListener {
void onEntryLongClick(String companyId);
}
...
OrgPreference switchPreference = new OrgPreference(getContext(), new OnEntryClickListener() {
@Override
public void onEntryLongClick(String companyId) {
//Do stuff
}
});
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.