【问题标题】:How to add a Progress Bar in a PreferenceFragment in Android?如何在 Android 的 PreferenceFragment 中添加进度条?
【发布时间】:2016-11-06 18:05:47
【问题描述】:

如何在 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>

我的问题是,由于这是一个 PreferenceFragment,并且我没有覆盖 onCreateView 方法,我应该在哪里以及如何添加进度条?

【问题讨论】:

    标签: android android-progressbar preferencefragment


    【解决方案1】:

    您可以尝试应用以下解决方案:

    在您的偏好活动中使用片段。

    • 当您需要显示首选项时 - 显示首选项片段。
    • 当您需要显示进度时 - 显示进度片段。

    这是一段代码摘录:

    @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();
            }
        });
    }
    

    【讨论】:

      【解决方案2】:

      我最终使用了以下方法。

      在我的 fragment_account.xml 布局文件中。

      <?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>
      

      然后在我的课上:

      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);
              }
          }
      
      }
      

      【讨论】:

        【解决方案3】:

        这就是我所做的:

        1. 创建一个自定义的 Preference 类:

          public class LoadingPreference extends Preference {
              public LoadingPreference(Context context){
                  super(context);
                  setLayoutResource(R.layout.preference_loading_placeholder);
              }
          }
          
        2. 创建自定义布局(preference_loading_placeholder),同时保留 Preference 布局:

          <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. 使用 PreferenceCategory 保存我的加载偏好:

          <?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. 将加载首选项放在需要的地方

          ((PreferenceCategory)findPreference(WIFI_OPTIONS_SECTION_KEY)).addPreference(new LoadingPreference(getActivity()));
          
        5. 加载完成后移除加载首选项:

          ((PreferenceCategory)findPreference(WIFI_OPTIONS_SECTION_KEY)).removeAll();
          
        6. 加载完成后添加其他首选项:

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

        【讨论】:

        • 谢谢。然而,我最终做了一些不同的事情。
        • 谢谢!它对我帮助很大;)
        【解决方案4】:

        我有一个类似的用例,我为偏好使用了自定义布局。

        在我拥有的偏好片段文件中(省略不相关的属性)

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

        然后在自定义布局中我自己放置了进度条

        <!-- 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>
        

        在开始我调用的异步任务之前

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

        当任务完成后,我将可见性设置为消失。这将允许您独立设置每个首选项,而无需等待每个首选项完成。希望这会有所帮助。

        【讨论】:

          【解决方案5】:

          在 AsyncTasks 默认方法中使用以下概念

          private class MyAsynTask extends AsyncTask<String, String, String> {
          
          @Override
          protected void onPreExecute() {
              super.onPreExecute();
              showDialog();// show your progressbar
          }
          
          @Override
          protected String doInBackground(String... urls) {
             //your code
          }
          
          protected void onProgressUpdate(String... progress) {        
          progressDialog.setProgress(Integer.parseInt(progress[0]));
          // here you get the value of progress
          }
          
          @Override
          protected void onPostExecute(String result) {           
              dismissDialog(); //dismiss progressbar
          }
           }
          

          【讨论】:

          • 谢谢,但我指的是应该放置进度条的部分,因为除了 pref_account.xml 之外,我没有夸大片段上的任何视图。
          猜你喜欢
          • 1970-01-01
          • 2012-04-17
          • 1970-01-01
          • 2016-04-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多