8

我正在尝试在 AsyncTask 和 Fragment 之间实现回调,但找不到正确的信息。问题是所有回调实现都在活动和异步任务之间,但我需要在片段和异步任务之间。有人可以给我一个小的工作示例,如何在没有活动的情况下实现它。我的动作结构:片段调用 DialogFragment -> 选择一些东西并将服务器请求发送到异步任务 -> 异步任务处理所有内容并更新视图和一些变量。我的主要问题是我在 onCreate 中只调用了一次 prepareData() ,当我在其他片段之间行走并返回时,我看到了旧数据。也就是说只更新asynctask的onPost中的view是不够的。最好有回调来更新整个变量。

public class TermsAndConditionsFragment extends SherlockFragment implements OnClickListener, OnTouchListener, OnItemClickListener, onTaskListener {
 @Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    fm = getSherlockActivity().getSupportFragmentManager();


    prepareData();
}

public void prepareData() {
     termsAndConditionsM = new TermsAndConditionsManager(getSherlockActivity());
    termsAndConditions = termsAndConditionsM.getTermsAndConditions();

    if (termsAndConditions != null) {
                 int totalPayments = Integer.valueOf(termsAndConditions.get(ServerAPI.NO_OF_PAYMENTS));
        if (totalPayments > 0) {
            paymentsData = termsAndConditionsM.getpayments();

            if (paymentsData != null) {

                payments = new ArrayList<Payment>();

                for (int i = 1; i <= totalPayments; i++) {
                    paymentValues = new Payment();
                    paymentValues.setPaymentID(Integer.valueOf(paymentsData.get(ServerAPI.PAYMENT_NO + "_" + i)));
                    paymentValues.setPaymentDate(paymentsData.get(ServerAPI.PAYMENT_DATE + "_" + i));
                    paymentValues.setPaymentTotalAmount(paymentsData.get(ServerAPI.PAYMENT_TOTAL + "_" + i));
                    payments.add(paymentValues);
                }
            }
        }
    }
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

    rootView = init(inflater, container);

    if (payments != null || termsAndConditions != null)
        updateTermsAndConditionsView();

    return rootView;
}

private View init(LayoutInflater inflater, ViewGroup container) {
    rootView = inflater.inflate(R.layout.fragment_terms_and_conditions, container, false);

    ...
    return rootView;
}

public void updateTermsAndConditionsView() {
    etHowMuch.setText("£" + termsAndConditions.get(ServerAPI.AMOUNT_OF_CREDIT));
    etForHowLong.setText(Helpers.ConvertDays2Date(Integer.valueOf(termsAndConditions.get(ServerAPI.TERM_OF_AGREEMENT_IN_DAYS))));

    PaymentAdapter adapter = new PaymentAdapter(getSherlockActivity(), R.layout.custom_loan_item, payments);
    lvPayments.setAdapter(adapter);

    tvNoOfPayments.setText(termsAndConditions.get(ServerAPI.NO_OF_PAYMENTS));
    tvFirstPayment.setText(termsAndConditions.get(ServerAPI.FIRST_PAYMENT_DATE));
    tvTotalRepayable.setText("£" + termsAndConditions.get(ServerAPI.TOTAL_REPAYABLE));
}

@Override
public void onClick(View v) {
    ft = fm.beginTransaction();

    howMuch = etHowMuch.getText().toString();
    forHowLong = etForHowLong.getText().toString();

    switch (v.getId()) {
        case R.id.etHowMuch:
            f = new NumberPaymentsPickerFragment();
            args = new Bundle();
            args.putInt(Const.HOW_MUCH, Integer.valueOf(howMuch.replace("£", "")));
            args.putDouble(ServerAPI.PAYMENT_STEP, Const.PAYMENT_STEP);
            args.putString(Const.STATE, ServerAPI.TERMS_AND_CONDITIONS);
            f.setArguments(args);
            f.setTargetFragment(this, DIALOG_FRAGMENT);
            f.show(getActivity().getSupportFragmentManager(), Const.HOW_MUCH);
            break;
        case R.id.etForHowLong:
            f = new NumberPaymentsPickerFragment();
            args = new Bundle();
            args.putInt(Const.FOR_HOW_LONG, Integer.valueOf(Helpers.ConvertDate2Days(forHowLong)));
            args.putDouble(ServerAPI.PAYMENT_STEP, Const.PAYMENT_STEP);
            args.putString(Const.STATE, ServerAPI.TERMS_AND_CONDITIONS);
            f.setArguments(args);
            f.setTargetFragment(this, DIALOG_FRAGMENT);
            f.show(getActivity().getSupportFragmentManager(), Const.FOR_HOW_LONG);
            break;
        case R.id.tvPersonalDetails:
            sfm.saveCurFragment(ServerAPI.PERSONAL_DETAILS, 0);
            ft.replace(android.R.id.content, new PersonalDetailsFragment(), ServerAPI.PERSONAL_DETAILS).addToBackStack(null).commit();
            break;
        case R.id.tvAgreementDetails:
            sfm.saveCurFragment(ServerAPI.AGREEMENT_DETAILS, 0);
            ft.replace(android.R.id.content, new AgreementDetailsFragment(), ServerAPI.AGREEMENT_DETAILS).addToBackStack(null).commit();
            break;
        case R.id.bApply:

            break;
    }

@Override
public void onUpdateData() {
    Log.d(TAG, "Update data");

}

}

对话片段:

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

    Bundle args = getArguments();

    ...
}

public Dialog onCreateDialog(Bundle savedInstanceState) {

    ...

        return createDialog(v, R.string.for_how_long, etHowMuch, etForHowLong, etPromotionCode);
    }
    return null;
}
private Dialog createDialog(View view, int titleResID, final EditText howMuchField, final EditText forHowLongField, final EditText promotionCodeField) {
    AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
    builder.setTitle(titleResID);
    builder.setView(view);
    builder.setPositiveButton(R.string.set, new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int id) {

            doShowProgress();

        }

        private void doShowProgress() {


            ExecuteServerTaskBackground task = new
                    ExecuteServerTaskBackground(getActivity());
                task.action = ServerAPI.GET_TERMS_AND_CONDITIONS;
                onTaskListener listener = new onTaskListener() {

                @Override
                public void onUpdateData() {
                    Log.d(TAG, "Updaaate");

                }
            };
            task.setListener(listener);
            task.args = args;
            task.execute();
        }

    }).setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int id) {
            dialog.cancel();
        }
    });
    return builder.create();
}

异步任务:

    onTaskListener mListener;

public interface onTaskListener {
    void onUpdateData();
}

public void setListener(onTaskListener listener){
  mListener = listener;
}
public ExecuteServerTaskBackground(Activity activity) {
    this.mActivity = activity;
    this.mContext = activity.getApplicationContext();
}

@Override
protected void onPreExecute() {
    pb = (ProgressBar) mActivity.findViewById(R.id.progressBar1);
    pb.setVisibility(View.VISIBLE);
}

@Override
protected Void doInBackground(Void... params) {
    ServerAPI server = new ServerAPI(mContext);
    if (!args.isEmpty())
        server.serverRequest(action, args);
    else
        server.serverRequest(action, null);
    return null;
}

@Override
protected void onPostExecute(Void result) {
 mListener.onUpdateData();

//There is I just update view but how to update whole variables throughtout callback?        
//                tvNoOfPayments = (TextView) mActivity.findViewById(R.id.tvNoOfPaymentsValue);
//                tvFirstPayment = (TextView) mActivity.findViewById(R.id.tvFirstPaymentValue);
//                tvTotalRepayable = (TextView) mActivity.findViewById(R.id.tvTotalRepayableValue);
//
//                lvPayments = (ListView) mActivity.findViewById(R.id.lvData);
//
//                termsConditionsM = new TermsAndConditionsManager(mContext);
//
//                termsAndConditions = termsConditionsM.getTermsAndConditions();
//
//                int totalPayments = Integer.valueOf(termsAndConditions.get(ServerAPI.NO_OF_PAYMENTS));
//
//                if (totalPayments > 0) {
//                    if (termsAndConditions != null) {
//                        tvNoOfPayments.setText(termsAndConditions.get(ServerAPI.NO_OF_PAYMENTS));
//                        tvFirstPayment.setText(termsAndConditions.get(ServerAPI.FIRST_PAYMENT_DATE));
//                        tvTotalRepayable.setText("£" + termsAndConditions.get(ServerAPI.TOTAL_REPAYABLE));
//                    }
//
//                    paymentsData = termsConditionsM.getpayments();
//
//                    if (paymentsData != null) {
//                        Log.d(TAG, paymentsData.toString());
//
//                        payments = new ArrayList<Payment>();
//
//                        for (int i = 1; i <= totalPayments; i++) {
//                            paymentValues = new Payment();
//                            paymentValues.setPaymentID(Integer.valueOf(paymentsData.get(ServerAPI.PAYMENT_NO + "_" + i)));
//                            paymentValues.setPaymentDate(paymentsData.get(ServerAPI.PAYMENT_DATE + "_" + i));
//                            paymentValues.setPaymentTotalAmount(paymentsData.get(ServerAPI.PAYMENT_TOTAL + "_" + i));
//                            payments.add(paymentValues);
//                        }
//
//                        PaymentAdapter adapter = new PaymentAdapter(mContext, R.layout.custom_loan_item, payments);
//                        lvPayments.setAdapter(adapter);
//                    }
    //             

   }

    pb.setVisibility(View.GONE);
    super.onPostExecute(result);
}
4

1 回答 1

26

在不考虑您的代码的情况下,我将发布最重要的功能回调。


测试片段:

public class TestFragment extends Fragment {

    /* Skipping most code and I will only show you the most essential. */    
    private void methodThatStartsTheAsyncTask() {
        TestAsyncTask testAsyncTask = new TestAsyncTask(new FragmentCallback() {

            @Override
            public void onTaskDone() {
                methodThatDoesSomethingWhenTaskIsDone();
            }
        });

        testAsyncTask.execute();
    }

    private void methodThatDoesSomethingWhenTaskIsDone() {
        /* Magic! */
    }

    public interface FragmentCallback {
        public void onTaskDone();
    }
}

测试异步任务:

public class TestAsyncTask extends AsyncTask<Void, Void, Void> {
    private FragmentCallback mFragmentCallback;

    public TestAsyncTask(FragmentCallback fragmentCallback) {
        mFragmentCallback = fragmentCallback;
    }

    @Override
    protected Void doInBackground(Void... params) {
        /* Do your thing. */
        return null;
    }

    @Override
    protected void onPostExecute(Void result) {
        mFragmentCallback.onTaskDone();
    }
}
于 2013-03-07T13:23:44.870 回答