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?
Here's what I did:
Create a custom Preference class:
public class LoadingPreference extends Preference {
public LoadingPreference(Context context){
super(context);
setLayoutResource(R.layout.preference_loading_placeholder);
}
}
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>
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>
Put the loading preference where needed
((PreferenceCategory)findPreference(WIFI_OPTIONS_SECTION_KEY)).addPreference(new LoadingPreference(getActivity()));
Remove the loading preference after loading is complete:
((PreferenceCategory)findPreference(WIFI_OPTIONS_SECTION_KEY)).removeAll();
Add other preferences after loading is complete:
Preference p = new Preference(getActivity());
p.setTitle("...");
p.setSumary("...")
((PreferenceCategory)findPreference(WIFI_OPTIONS_SECTION_KEY)).addPreferece(p);
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.
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);
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With