ads
ads

Reputation: 1723

How to add a Progress Bar in a PreferenceFragment in Android?

How can I add a progress bar in a PreferenceFragment? I have some async task running that will display some values in my preference upon completion. So while it is doing the background process, I plan to show only a progress bar in the center. After the task is complete, then I plan to show all my preferences.

Here's what I have so far.

PreferenceFragment

@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.xml.pref_account);
    }

@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    new AsyncTask<Void,Void,Void>() {

        String firstName, lastName, email;
        @Override
        protected void doInBackground() {
            // Doing something here to fetch values
        }

        @Override
        protected void onPostExecute() {
            findPreference("first_name").setSummary(firstName);
            findPreference("last_name").setSummary(lastName);
            findPreference("email").setSummary(email);
        }
    }
}

pref_account.xml

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">

    <Preference android:key="first_name"
        android:title="@string/prompt_first_name"
        android:summary="" />

    <Preference android:key="last_name"
        android:title="@string/prompt_last_name"
        android:summary="" />

    <Preference android:key="email"
        android:title="@string/prompt_email"
        android:summary=""
        android:inputType="textEmailAddress" />

    <Preference android:key="sign_out"
        android:title="@string/action_sign_out" />

</PreferenceScreen>

My question is, since this is a PreferenceFragment and I'm not overriding the method onCreateView, where and how should I add the progress bar?

Upvotes: 9

Views: 4494

Answers (5)

Sachin Gurnani
Sachin Gurnani

Reputation: 2444

Use this approach. Create one Dialog with a custom layout which a progressBar in it and just call show() and dismiss().

@Synchronized
fun showLoader(activity: Activity) {
        val activityWeakReference = WeakReference(activity)
        if (activityWeakReference.get() != null) {
            hideLoader()
            dialog = Dialog(activityWeakReference.get()!!, android.R.style.Theme_Translucent)
            dialog?.window?.requestFeature(Window.FEATURE_NO_TITLE)
            dialog?.setContentView(R.layout.progress_indicator)
            dialog?.setCancelable(false)
            dialog?.show()
        }
    }


@Synchronized
fun hideLoader() {
    dialog?.dismiss()
    dialog = null
}

Upvotes: 0

GregoryK
GregoryK

Reputation: 3091

You could try to apply the following solution:

Use fragments in your preference activity.

  • When you need to display preferences - display preference fragment.
  • When you need to display progress - display progress fragment.

Here is a code excerpt:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    showPreferences();
    // or call showProgress, launch your task and call showPreferences upon completion
}

private void showPreferences() {
    runOnUiThread(new Runnable() {
        @Override
        public void run() {
            getFragmentManager()
                    .beginTransaction()
                    .replace(android.R.id.content, new YourPreferenceFragment())
                    .commit();
        }
    });
}

private void showProgress() {
    runOnUiThread(new Runnable() {
        @Override
        public void run() {
            getFragmentManager()
                    .beginTransaction()
                    .replace(android.R.id.content, new YourProgressFragment())
                    .commit();
        }
    });
}

Upvotes: 0

ads
ads

Reputation: 1723

I ended up using the following approach.

In my fragment_account.xml layout file.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ProgressBar
        android:id="@+id/progress_bar"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true" />

    <ListView
        android:id="@android:id/list"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:visibility="gone" />

</RelativeLayout>

Then on my class:

public class AccountFragment extends PreferenceFragment {

        private ListView mListView;
        private ProgressBar mProgressBar;

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

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            View view = inflater.inflate(R.layout.fragment_account, container, false);

            mListView = (ListView) view.findViewById(android.R.id.list);
            mProgressBar = (ProgressBar) view.findViewById(R.id.progress_bar);

            showProgress();

            return view;
        }

        @Override
        public void onActivityCreated(Bundle savedInstanceState) {
            super.onActivityCreated(savedInstanceState);
            addPreferencesFromResource(R.xml.pref_account);
            hideProgress();
        }

        private void showProgress() {
            mListView.setVisibility(View.GONE);
            mProgressBar.setVisibility(View.VISIBLE);
        }

        private void hideProgress() {
            mListView.setVisibility(View.VISIBLE);
            mProgressBar.setVisibility(View.GONE);
        }
    }

}

Upvotes: 1

Aaron Preston
Aaron Preston

Reputation: 111

Here's what I did:

  1. Create a custom Preference class:

    public class LoadingPreference extends Preference {
        public LoadingPreference(Context context){
            super(context);
            setLayoutResource(R.layout.preference_loading_placeholder);
        }
    }
    
  2. Create a custom Layout (preference_loading_placeholder) while preserving the Preference layout:

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:minHeight="?android:attr/listPreferredItemHeight"
        android:gravity="center_vertical"
        android:paddingEnd="?android:attr/scrollbarSize"
        android:background="?android:attr/selectableItemBackground" >
    
        <ImageView
            android:id="@+android:id/icon"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:layout_gravity="center"/>
    
        <RelativeLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="15dip"
            android:layout_marginEnd="6dip"
            android:layout_marginTop="6dip"
            android:layout_marginBottom="6dip"
            android:layout_weight="1">
    
            <!-- (start) I added this part. -->
    
            <ProgressBar
                android:id="@+id/progressBar"
                android:layout_centerInParent="true"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:indeterminateTintMode="src_atop"
                android:indeterminateTint="@color/colorAccent"
                android:layout_gravity="center" />
    
            <TextView
                android:id="@+id/progressTitle"
                android:text="@string/loading"
                android:textSize="24sp"
                android:textColor="@color/colorAccent"
                android:layout_centerVertical="true"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginRight="16dp"
                android:layout_toLeftOf="@+id/progressBar" />
    
            <!-- (end) I added this part. -->
    
            <TextView android:id="@+android:id/title"
                android:layout_width="0dp"
                android:layout_height="0dp"
                android:singleLine="true"
                android:textAppearance="?android:attr/textAppearanceLarge"
                android:ellipsize="marquee"
                android:fadingEdge="horizontal" />
    
            <TextView android:id="@+id/summary"
                android:layout_width="0dp"
                android:layout_height="0dp"
                android:layout_below="@android:id/title"
                android:layout_alignStart="@android:id/title"
                android:textAppearance="?android:attr/textAppearanceSmall"
                android:textColor="?android:attr/textColorSecondary"
                android:maxLines="4" />
    
        </RelativeLayout>
    
        <!-- Preference should place its actual preference widget here. -->
        <LinearLayout android:id="@+id/widget_frame"
             android:layout_width="wrap_content"
             android:layout_height="match_parent"
             android:gravity="center_vertical"
             android:orientation="vertical"/>
    
    </LinearLayout>
    
  3. Used a PreferenceCategory to hold my loading preference:

    <?xml version="1.0" encoding="utf-8"?>
    <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
    
        <SwitchPreference
            android:key="@string/pref_key_wifi_enabled"
            android:title="@string/pref_title_wifi_enabled"
            android:summary="@string/pref_summary_wifi_enabled" />
    
        <Preference
            android:key="@string/pref_key_wifi_refresh"
            android:title="@string/pref_title_wifi_refresh"
            android:summary="@string/pref_summary_wifi_refresh"
            android:dependency="@string/pref_key_wifi_enabled"/>
    
        <PreferenceCategory
            android:key="@string/pref_key_wifi_section"
            android:title="@string/pref_title_wifi_section"
            android:summary="@string/pref_summary_wifi_section"
            android:dependency="@string/pref_key_wifi_enabled"/>
    
    </PreferenceScreen>
    
  4. Put the loading preference where needed

    ((PreferenceCategory)findPreference(WIFI_OPTIONS_SECTION_KEY)).addPreference(new LoadingPreference(getActivity()));
    
  5. Remove the loading preference after loading is complete:

    ((PreferenceCategory)findPreference(WIFI_OPTIONS_SECTION_KEY)).removeAll();
    
  6. Add other preferences after loading is complete:

    Preference p = new Preference(getActivity());
    p.setTitle("...");
    p.setSumary("...")     
    ((PreferenceCategory)findPreference(WIFI_OPTIONS_SECTION_KEY)).addPreferece(p);
    

Loading Fragment Example

Upvotes: 10

Liviu
Liviu

Reputation: 148

I had a similar use case and I used a custom layout for the preference.

In the preference fragment file I had (non relevant attributes are omitted)

<!-- res/xml/somePref.xml -->
<PreferenceScreen>
    <PreferenceCategory>
        ...
        <Preference android:widgetLayout="@layout/customLayout" />
        ...
    </PreferenceCategory>
</PreferenceScreen>

Then in the custom layout I placed the progress bar by itself

<!-- res/layout/customLayout.xml -->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/progress"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:visibility="gone">

    <ProgressBar
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:indeterminateOnly="true" />

</RelativeLayout>

Before starting the async task I call

findViewById(R.id.progress).setVisibility(View.VISIBLE)

and when the task is done I set the visibility back to gone. This will allow you to set each preference independently without having to wait for each one to complete. Hope this helps.

Upvotes: 8

Related Questions