如何使用 DialogFragment 显示 AsyncTask 的进度 - 不使用 ProgressDialog

Posted

技术标签:

【中文标题】如何使用 DialogFragment 显示 AsyncTask 的进度 - 不使用 ProgressDialog【英文标题】:How to use DialogFragment for showing progress from an AsyncTask - without using ProgressDialog 【发布时间】:2019-01-19 00:03:45 【问题描述】:

这个网站已经帮助了我一年了,这是我第一次找不到我的问题的答案。

我正在尝试从 没有 ProgressDialog 的 AsyncTask 发布进度。用户刚刚输入了一个地址,我想在地图和列表中显示该地址的某个半径范围内的景点。因此,我需要从数据库中获取这些地点的地址并计算距离,然后才能知道需要在地图上显示哪些地点作为标记。

在计算距离时(在 AsyncTask 中),我希望在标记最终显示在地图上之前让用户了解进度。

我的代码存在的两个主要问题:

它将正确显示和关闭 DialogFragment,但不会不显示进度(既不通过栏,也不通过数字) 我不想使用 ProgressDialog

非常感谢任何提示或建议!

我的 AsyncTask 如下所示:

public class GetDistanceTask extends AsyncTask<Void,Integer,Integer>


private Location mSearchAddress;
private FragmentManager mSfm;
private ContentResolver mCr;
private static final String TAG = GetDistanceTask.class.getSimpleName();
private DialogFragment mDf;
private ProgressDialog mProgressDialog;

public GetDistanceTask(FragmentManager sfm, ContentResolver cr, Location searchAddress)
    mSfm = sfm;
    mCr = cr;
    mSearchAddress = searchAddress;


@Override
protected Integer doInBackground(Void...voids) 
    int rowsUpdated = 0;
    int max = 0;
    final Uri locationUri = KitaContract.LocationEntry.CONTENT_URI;
    String selection = KitaProvider.sLocationKitaSelection;
    String[] args = new String[] "3";
    //All entries, unsorted
    Cursor cursor = mCr.query(locationUri, null, selection, args, null);
    if (cursor != null) 
        max = cursor.getCount();
        cursor.moveToFirst();
     else 
        Log.e(TAG, "Cursor == null !");
        return 0;
    
        do
            double kitaLat = cursor.getDouble(COL_LAT);
            double kitaLong = cursor.getDouble(COL_LONG);
            int id = cursor.getInt(COL_LOCID);

            //make a Location-object from Kita's Lat & Long
            Location kitaAddress = new Location("kitaName");
            kitaAddress.setLatitude(kitaLat);
            kitaAddress.setLongitude(kitaLong);
            //calculate distance
            float distance = kitaAddress.distanceTo(mSearchAddress);
            ContentValues contentValues = new ContentValues();
            contentValues.put(KitaContract.LocationEntry.COLUMN_DIST, distance);

            //add the distance to the kita entry in the database
            int rowUpdated =mCr.update(
                    locationUri,
                    contentValues,
                    KitaContract.LocationEntry._ID + " = ?",
                    new String[] String.valueOf(id));
            rowsUpdated += rowUpdated;
            publishProgress(rowsUpdated, max);
        while (cursor.moveToNext());
    cursor.close();


    return rowsUpdated;


@Override
protected void onPreExecute() 
    super.onPreExecute();
    // instantiate ProgressDialog
    mDf = (DistanceProgressDialogFragment) mSfm.findFragmentByTag("dpdf_tag");
    if (mDf == null)
        mDf = new DistanceProgressDialogFragment();
        mSfm.beginTransaction()
                .add(mDf, "dpdf_tag")
                .commitAllowingStateLoss();
    
    else mDf.show(mSfm, "dpdf_tag");

    if (mDf != null) 
        mProgressDialog = (ProgressDialog) mDf.getDialog();
        mProgressDialog.setProgressNumberFormat("%1d/%2d Kitas");
    


@Override
protected void onProgressUpdate(Integer... progress) 
    mProgressDialog.setMax(progress[1]);
    mProgressDialog.setProgress(progress[0]);
    super.onProgressUpdate(progress);


@Override
protected void onPostExecute(Integer rowsUpdated) 
    if ( mDf != null) 
        mDf.dismiss();
    

我的 DialogFragment 是这样的:

public class DistanceProgressDialogFragment extends DialogFragment


@Override
public void onCreate(Bundle savedInstanceState)

    super.onCreate(savedInstanceState);
    setCancelable(false);




@NonNull
@Override
public ProgressDialog onCreateDialog(Bundle savedInstanceState)

    ProgressDialog dialog = new ProgressDialog(getActivity(), getTheme());
    dialog.setTitle("Kita Guide");
    dialog.setMessage("Suche Kitas in der Nähe");
    dialog.setIndeterminate(true);
    dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
    return dialog;


【问题讨论】:

【参考方案1】:

dialog.setIndeterminate(true); 表示进度条应该永远运行。

【讨论】:

非常感谢!这是修复它的阶梯。我的主要错误是我总是在“mProgressDialog.setMax(progress[1])”上得到一个“空指针异常”,因为显然我在 DialogFragment 中的 onCreateDialog() 执行之前调用了“mDf.getDialog()”。调用“mSfm.executePendingTransactions();”对我有用。

以上是关于如何使用 DialogFragment 显示 AsyncTask 的进度 - 不使用 ProgressDialog的主要内容,如果未能解决你的问题,请参考以下文章

如何从 DialogFragment 中删除标题?

如何在 DialogFragment 中显示现有的 ListFragment

如何在xamarin android的MainActivity上的dialogFragment中显示editText的文本?

如何使用RxJava管理DialogFragment?

手把手带你玩转 DialogFragment

允许 DialogFragment 的外部触摸