【问题标题】:How to pass date from one fragment to another in the same activity in Android?如何在 Android 的同一活动中将日期从一个片段传递到另一个片段?
【发布时间】:2017-06-01 12:43:02
【问题描述】:

我无法将数据(用户从日期小部件中选择的日期)从小部件传回调用片段并将其设置在按钮上。起始片段成功地将当前日期传递给小部件,但无法将用户选择的日期传递回调用片段。

这里是起始片段的代码,即犯罪片段

package com.khalsa.gurankassingh.criminalintent;


import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.text.Editable;
import android.text.TextWatcher;
import android.text.format.DateFormat;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.EditText;

import java.util.Date;
import java.util.UUID;

/**
 * Created by Gurankas Singh on 3/12/2017.
 */

public class CrimeFragment extends Fragment
{
    public static final String ARG_CRIME_ID = "crime_id";
    public static final String DIALOG_DATE = "DialogDate";

private static final int REQUEST_DATE = 0;

private Crime mCrime;               //instance of the Crime class
private EditText mTitleField;       // The editable text field in the fragment
private Button mDateButton;         //Displays the date of the crime on the button
private CheckBox mSolvedCheckBox;   //Displays the current status of the crime; solved or unsolved

public static CrimeFragment newInstance(UUID crimeID)           //to pass value to the fragment via an arguement to another fragment
{
    Bundle args = new Bundle();
    args.putSerializable(ARG_CRIME_ID,crimeID);

    CrimeFragment fragment = new CrimeFragment();
    fragment.setArguments(args);
    return fragment;
}

@Override
public void onCreate(@Nullable Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    UUID crimeId = (UUID)getArguments().getSerializable(ARG_CRIME_ID);
    mCrime = CrimeLab.get(getActivity()).getCrime(crimeId);

}

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState)
{
    View v = inflater.inflate(R.layout.fragment_crime,container,false);

    mTitleField = (EditText) v.findViewById(R.id.crime_title);
    mTitleField.setText(mCrime.getTitle());
    mTitleField.addTextChangedListener(new TextWatcher()
    {
        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after)
        {

        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count)
        {
            mCrime.setTitle(s.toString());
        }

        @Override
        public void afterTextChanged(Editable s)
        {

        }
    });

    mDateButton = (Button) v.findViewById(R.id.crime_date);
    updateDate();
    mDateButton.setOnClickListener(new View.OnClickListener()
    {

        @Override
        public void onClick(View v)
        {
            FragmentManager fragmentManager = getFragmentManager();
            DatePickerFragment dialog = DatePickerFragment.newInstance(mCrime.getDate());
            setTargetFragment(CrimeFragment.this,REQUEST_DATE);
            dialog.show(fragmentManager, DIALOG_DATE);
        }
    });

    mSolvedCheckBox = (CheckBox) v.findViewById(R.id.crime_solved);
    mSolvedCheckBox.setChecked(mCrime.isSolved());
    mSolvedCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener()
    {
        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
        {
            //set the crime's solved property
            mCrime.setSolved(isChecked);
        }
    });

    return v;
}

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data)
{
    if (resultCode != Activity.RESULT_OK)
    {
        return;
    }
    if (requestCode == REQUEST_DATE)
    {
        Date date = (Date)data.getSerializableExtra(DatePickerFragment.EXTRA_DATE);
        mCrime.setDate(date);
        updateDate();
    }
}

private void updateDate()
{
    mDateButton.setText(DateFormat.format("EEEE, d MMMM, yyy", mCrime.getDate()));
}
}

这是 DatePickerFragment 托管的 datePicker 小部件的代码

package com.khalsa.gurankassingh.criminalintent;

import android.app.Activity;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.DialogFragment;
import android.support.v7.app.AlertDialog;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.DatePicker;

import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

/**
 * Created by Gurankas Singh on 4/9/2017.
 */

public class DatePickerFragment extends DialogFragment
{
    private static final String DATE_ARG = "date";
public static final String EXTRA_DATE = "com.khalsa.gurankassingh.criminalintent.date";

private DatePicker mDatePicker;

public static DatePickerFragment newInstance(Date date)
{
    Bundle args = new Bundle();
    args.putSerializable(DATE_ARG,date);

    DatePickerFragment fragment = new DatePickerFragment();
    fragment.setArguments(args);
    return fragment;
}

@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState)
{
    Date date = (Date)getArguments().getSerializable(DATE_ARG);

    Calendar calendar = Calendar.getInstance();
    calendar.setTime(date);
    int year = calendar.get(Calendar.YEAR);
    int month = calendar.get(Calendar.MONTH);
    int day = calendar.get(Calendar.DAY_OF_MONTH);

    View v = LayoutInflater.from(getActivity()).inflate(R.layout.dialog_date,null);

    mDatePicker = (DatePicker)v.findViewById(R.id.dialog_date_date_picker);
    mDatePicker.init(year,month,day,null);

    return new AlertDialog.Builder(getActivity()).setView(v).setTitle(R.string.date_picker_title).setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener()
    {
        @Override
        public void onClick(DialogInterface dialog, int which)
        {
            int year = mDatePicker.getYear();
            int month = mDatePicker.getMonth();
            int day = mDatePicker.getDayOfMonth();
            Date date = new GregorianCalendar(year, month, day).getTime();
            sendResult(Activity.RESULT_OK, date);
        }
    }).create();
}
private void sendResult(int resultCode, Date date)
{
    if (getTargetFragment() == null)
    {
        return;
    }
    Intent intent = new Intent();
    intent.putExtra(EXTRA_DATE,date);

    getTargetFragment().onActivityResult(getTargetRequestCode(), resultCode, intent);
}

}

【问题讨论】:

  • 你的意思是一个片段到另一个片段?
  • 在activity中创建一个接口,在fragment事务时在fragment之间传递数据。参考here
  • @Rajasekhar 是的。上面给出的两个片段由同一个活动托管。我需要将用户选择的日期传递回原始片段

标签: java android android-fragments


【解决方案1】:

要在Fragments 之间传递数据,您只需要知道:

1- 要从ActivityFragment 传递数据,请使用对象实例,当您在Activity 中创建Fragment 时,您有一个实例,因此使用它来传递如下数据:

class Activity1 extend AppCompatActivity {

   Fragment1 fragment;

   void doSomethingInFramgent() {

      fragment.doSomething();
   }
}

2- 要将数据从Fragment 传递到Activity,请使用Interface,创建Interface 并使用以下步骤:

2-1- 创建Interface 文件:

public interface FragmentInteraction {
     void doSomethingInActivity();
}

2-2- 在Activity 中实现Interface

 class Activity1 extend AppCompatActivity implement FragmentInteraction {

    void doSomethingInActivity() {
       // do whatever you need
    }
 }

2-3- 从Interface 创建一个对象并在onAttach 中初始化它,如下所示:

   class Fragment1 extend Fragment {

   FragmentInteraction fragmentInteraction;

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);

        if (context instanceof FragmentInteraction) {
            fragmentInteraction = (FragmentInteraction) context;
        }
    }

}

2-4- 使用Interfaceinstance 调用Activity 中的方法如:

fragmentInteraction.doSomethinInActivity();

使用这个概念,您可以在FragmentsActivity 之间传递数据,例如,如果您想在不同的活动中将数据从一个片段传递到另一个片段,您可以:

活动 1,片段 1。 Activity2,Fragment2

InterfaceFragment1传递数据到Activity1,用startActivityForResult开始Activity2,用fragment2对象传递数据,用Interface返回数据到Activity2然后使用setResult并返回Activity1

PS:如果你想在创建Fragment对象时传递数据,你可以使用Argument传递数据。

为此,您可以按如下方式使用:

1- 为获取片段实例创建静态方法:

 public static Fragment1 getInstance(String data1) {

        Fragment1 fragment = new Fragment1();

        Bundle bundle = new Bundle();
        bundle.putString(KEY, data1);
        fragment.setArguments(bundle);

        return fragment;
    }

然后在onCreateView onViewCreate 上获取您的数据,例如:

 if (getArguments() != null) {
     data = getArguments().getString(KEY);    
 }

【讨论】:

    【解决方案2】:

    你可以试试这个解决方案:-

    => 在 CrimeFragment 中更改以下代码

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data)
    {
        if (resultCode != Activity.RESULT_OK)
        {
            return;
        }
        if (requestCode == REQUEST_DATE)
        {
            long dateValue = data.getLongExtra(DatePickerFragment.EXTRA_DATE,System.currentTimeMillis());
            Date date = new Date(dateValue);
            mCrime.setDate(date);
            updateDate();
        }
    }
    

    并在 DatePickerFragment 中更改以下代码:-

    private void sendResult(int resultCode, Date date)
            {
                if (getTargetFragment() == null)
                {
                    return;
                }
                Intent intent = new Intent();
                intent.putExtra(EXTRA_DATE, date.getTime());
    
                getTargetFragment().onActivityResult(getTargetRequestCode(), resultCode, intent);
            }
    

    ....

    【讨论】:

    • @Gurankas 你的 dateObject 是否需要 time(hh:MM:ss) ?
    • @Gurankas 上面的代码工作正常。您应该必须在 DatePickerFragment 的 sendResult() 方法中调试和检查日期对象值。我认为它没有正确设置。希望这会对你有所帮助。
    • 当我实现上述代码时,应用程序崩溃了。您如何建议我调试和检查在 sendResult 中发送的日期对象的值?
    • 我想是的。知道如何测试它吗?
    【解决方案3】:

    你好试试这个方法,

    您可以使用共享首选项来存储日期,以后您可以在需要时访问它,这更容易处理。请记住日期格式并相应地选择 SimpleDateFormat,因为它提供如果输入日期的格式不同,则解析错误。

    写入 SharedPreferences

    SharedPreferences sharedpreferences;
    sharedpreferences = getSharedPreferences("myPref", Context.MODE_PRIVATE);
    SharedPreferences.Editor editor = sharedpreferences.edit();
                editor.putString("Date",String.valueOf(date);
                editor.commit();
    

    在需要时阅读 SharedPreferences

    SharedPreferences prefs = this.getSharedPreferences("myPref", Context.MODE_PRIVATE);
    String dateCrime = prefs.getString("Date", null);  
    
    //Chose Date format depending on your date
    SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");  
    try {  
        Date date = format.parse(dateCrime);   
    } catch (ParseException e) {    
        e.printStackTrace();  
    } 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-14
      • 1970-01-01
      • 2015-12-18
      • 2016-06-12
      • 1970-01-01
      • 2020-05-31
      相关资源
      最近更新 更多