javaandroidandroid-custom-viewpreferencescreen

How to create custom PreferenceScreen Class in java and set custom layout to it?


I want to create a custom PreferenceScreen class in java having custom layout set to it. I have create the custom class for ListPreference, CheckboxPreference and set custom views. But PreferenceScreen is final class, so it is not extendable.Is there any way of using this PreferenceScreen class?, so that i can set custom view and also use its methods for its functionality. Here is the code of PreferenceScreen:


    `   <androidx.preference.PreferenceScreen
            android:enabled="false"
            android:key="bg_keys"
            android:persistent="false"
            android:summary="@string/cv19"
            app:icon="@drawable/d5"
            android:layout="@layout/background_settings_"
            android:title="@string/cv20">

            <CustomListPreference
                android:entries="@array/backgroundnames"
                android:entryValues="@array/backgroundvalues"
                android:key="baund_
                android:summary="@string/summary"
                android:title="@string/title" />

            <CustomListPreference
                android:entries="@array/btnames"
                android:entryValues="@array/btvalues"
                android:key="btvalue"
                android:title="@string/titlefome" />


        </androidx.preference.PreferenceScreen>`


The below is the CustomListPreference class which i have created and set custom view, which is working absolutely fine:



`public class CustomListPreference extends ListPreference {

    public CustomListPreference(@NonNull Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }
    public CustomListPreference(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        setLayoutResource(R.layout.custom_list_preference_layout);

    }

    @Override
    public void onBindViewHolder(PreferenceViewHolder holder) {
        super.onBindViewHolder(holder);
        holder.itemView.setClickable(true); // disable parent click
        ImageView customIcon = (ImageView) holder.findViewById(R.id.ivPreferenceIcon);
        TextView customTitle = (TextView) holder.findViewById(R.id.tvTitle);
        TextView customSummery = (TextView) holder.findViewById(R.id.tvSummary);
        LinearLayout llBackground = (LinearLayout) holder.findViewById(R.id.llBackground);
        customIcon.setImageDrawable(getIcon());
        customTitle.setText(getTitle());
        customSummery.setText(getSummary());


        if (isEnabled()){
            llBackground.setBackground(getContext().getResources().getDrawable(R.drawable.playlist_rect_box_shape));
            customTitle.setTextColor(Color.parseColor("#ffffff"));
            customSummery.setTextColor(Color.parseColor("#807d7d"));
        }else {
            llBackground.setBackground(getContext().getResources().getDrawable(R.drawable.playlist_rect_box_disabled));
            customTitle.setTextColor(Color.parseColor("#999999"));
            customSummery.setTextColor(Color.parseColor("#6A6868"));
        }
    }

}`



So, I want Custom PreferenceScreen class like i have created above to set custom view, which will work like PreferenceScreen. But the PreferenceScreen class is final class,

here it is:


`

`/*
 * Copyright 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package androidx.preference;

import static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX;

import android.content.Context;
import android.util.AttributeSet;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RestrictTo;
import androidx.core.content.res.TypedArrayUtils;

/**
 * A top-level container that represents a settings screen. This is the root component of your
 * {@link Preference} hierarchy. A {@link PreferenceFragmentCompat} points to an instance of this
 * class to show the preferences. To instantiate this class, use
 * {@link PreferenceManager#createPreferenceScreen(Context)}.
 *
 * <div class="special reference">
 * <h3>Developer Guides</h3>
 * <p>For information about building a settings screen using the AndroidX Preference library, see
 * <a href="{@docRoot}guide/topics/ui/settings.html">Settings</a>.</p>
 * </div>
 *
 */
public final class PreferenceScreen extends PreferenceGroup {

    private boolean mShouldUseGeneratedIds = true;

    /**
     * Do NOT use this constructor, use {@link PreferenceManager#createPreferenceScreen(Context)}.
     *
     * Used by Settings :)
     *
     * @hide
     */
    @RestrictTo(LIBRARY_GROUP_PREFIX)
    public PreferenceScreen(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs, TypedArrayUtils.getAttr(context, R.attr.preferenceScreenStyle,
                android.R.attr.preferenceScreenStyle));
    }

    @Override
    protected void onClick() {
        if (getIntent() != null || getFragment() != null || getPreferenceCount() == 0) {
            return;
        }
        final PreferenceManager.OnNavigateToScreenListener listener =
                getPreferenceManager().getOnNavigateToScreenListener();
        if (listener != null) {
            listener.onNavigateToScreen(this);
        }
    }

    @Override
    protected boolean isOnSameScreenAsChildren() {
        return false;
    }

    /**
     * See {@link #setShouldUseGeneratedIds(boolean)}
     *
     * @return {@code true} if the adapter should use the preference IDs generated by
     * {@link PreferenceGroup#addPreference(Preference)} as stable item IDs.
     */
    public boolean shouldUseGeneratedIds() {
        return mShouldUseGeneratedIds;
    }

    /**
     * Set whether the adapter created for this screen should attempt to use the preference IDs
     * generated by {@link PreferenceGroup#addPreference(Preference)} as stable item IDs. Setting
     * this to false can suppress unwanted animations if {@link Preference} objects are frequently
     * removed from and re-added to their containing {@link PreferenceGroup}.
     *
     * <p>This method may only be called when the preference screen is not attached to the
     * hierarchy.
     *
     * <p>Default value is {@code true}.
     *
     * @param shouldUseGeneratedIds {@code true} if the adapter should use the preference ID as a
     *                              stable ID, or {@code false} to disable the use of
     *                              stable IDs.
     */
    public void setShouldUseGeneratedIds(boolean shouldUseGeneratedIds) {
        if (isAttached()) {
            throw new IllegalStateException("Cannot change the usage of generated IDs while" +
                    " attached to the preference hierarchy");
        }
        mShouldUseGeneratedIds = shouldUseGeneratedIds;
    }
}`

`

So, please help me, how can i use this class and set custom view if possible. Thank you for help!


Solution

  • I get the answer. Created custom UI for this and set it to the PreferenceScreen layout property. It was not possible to extend the by default final class of PreferenceScreen. Otherwise, we have to create the lots of classes supporting PreferenceScreen Class functionality, which will be more time consuming.