2013-03-07 6 views
8

私はAsyncTaskとFragmentの間でコールバックを実装しようとしていますが、どのように正しい情報を見つけることができません。問題は、すべてのコールバック実装がアクティビティとasynctaskの間にあることですが、私はフラグメントとasynctaskの間に必要です。誰かが、私に活動なしでそれを実装する方法を小さな実例として教えてもらえますか? 私のアクション構造:フラグメントコールDialogFragment - >何かを選択し、サーバ要求をasyncタスク - > asyncタスクのすべてに送信し、ビューといくつかの変数を更新します。私の主な問題は、prepareData()をonCreateで一度だけ呼び出すことで、他のフラグメントと歩き回って戻るときに戻ると古いデータが表示されることです。つまり、asynctaskのonPostのビューのみを更新するには十分ではありません。変数全体を更新するコールバックを持つと良いでしょう。Android:Callback AsyncTask to Fragment(アクティビティではない)

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

} 

} 

DialogFragment:

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

AsyncTask:

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

答えて

25

考慮して、あなたのコードを取らずに、私は、機能コールバックを行うために最も重要なを掲載します。


TestFragment:

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

TestAsyncTask:私が今持っているものである

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

。この部分は動作していますが、AsyncTaskと同じ場所ではなく、メッセージをキャッチしたいと思います。私の構造はMainFragment(ここで私はメッセージをキャッチしたい) - > DialogFragment(呼び出しasynctask) - >非同期タスク(処理し、結果をminフラグメントで返す)です。今、コールバックはDialogFragmentとAsyncTask間の接続のためだけに正常に動作しますが、結果をmainFragmentに直接送る方法はありますか? – user1376885

+0

2つのコールバック(1つのコールバック - AsyncTask - > DialogFragment、2コールバック - DialogFragment-> MainFragment)でしかできない場合、リスナーをDialogFragmentに送信する方法です。 AsyncTaskと同じようにsetLIstenerを使用することはできません。 – user1376885

+0

@ user1376885結果をデータベースに保存するか、保存できないものをロードしますか?良い方法は、ステートレスなアプローチを維持することです。つまり、フラグメントやアクティビティ間で直接的に物を送ることはありません。これをデータベースに保存し、フラグメント/アクティビティの開始時にデータベースを読み込み、値をロードして提示します。 AsyncTaskで何をやっているのですか?それをデータベースに保存できるようです。 –

関連する問題