【问题标题】:Passing argument from a fragment to its container activity将参数从片段传递到其容器活动
【发布时间】:2016-11-24 12:23:40
【问题描述】:

我有两个fragmentstimedate picker。 我需要发送用户从片段中选择的数据并将它们传递给fragments activity,以便合并数据并将其发送给另一个activity。 我使用了这个解决方案Link,但数据是null

这是FragmentOne - FramentTwo 是一样的

public FragmentOne(){}

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

   //FROM SIDE
   timeButtonFrom = (Button)view.findViewById(R.id.time_button);
   dateButtonFrom = (Button)view.findViewById(R.id.date_button);
   tvDateFrom = (TextView)view.findViewById(R.id.time_textview);
   tvTimeFrom = (TextView)view.findViewById(R.id.date_textview);


    timeButtonFrom.setOnClickListener(new View.OnClickListener() {
       @Override
       public void onClick(View view) {
           Calendar now = Calendar.getInstance();
           // TimePickerDialog tpd = TimePickerDialog.newInstance(
           TimePickerDialog tpd = TimePickerDialog.newInstance(
                   FragmentOne.this,
                   now.get(Calendar.HOUR_OF_DAY),
                   now.get(Calendar.MINUTE),true);//24H Enable, If 12 set false
           tpd.setThemeDark(true);
           tpd.enableMinutes(true);
           tpd.setTitle("Choose Time");
           tpd.setTimeInterval(1,15);//setTimeInterval to 1H and 15Min


           tpd.setOnCancelListener(new DialogInterface.OnCancelListener() {
               @Override
               public void onCancel(DialogInterface dialogInterface) {
                   Log.d("TimePicker", "Dialog was cancelled");
               }
           });

           tpd.show(getFragmentManager(), "ChooseTimeFrom");
       }
   });// end Button Listener FROM

   dateButtonFrom.setOnClickListener(new View.OnClickListener() {
       @Override
       public void onClick(View view) {
           Calendar now = Calendar.getInstance();
           DatePickerDialog dpd = DatePickerDialog.newInstance(
                   FragmentOne.this,
                   now.get(Calendar.YEAR),
                   now.get(Calendar.MONTH),
                   now.get(Calendar.DAY_OF_MONTH)
           );
           dpd.setThemeDark(true);
           dpd.showYearPickerFirst(true);
           dpd.setTitle("Choose Date");
           dpd.show(getFragmentManager(), "ChooseDateFrom");
       }
   });//END DATEBUTTONFROM
  return  view;

}//END ONCREATEVIEW

@Override
public void onResume() {
    super.onResume();
    DatePickerDialog dpd = (DatePickerDialog) getFragmentManager().findFragmentByTag("ChooseDateFrom");
    if(dpd != null) dpd.setOnDateSetListener(this);
    TimePickerDialog tpd = (TimePickerDialog) getFragmentManager().findFragmentByTag("ChooseTimeFrom");
    if(tpd != null) tpd.setOnTimeSetListener(this);

}



@Override
public void onDateSet(DatePickerDialog view, int year, int monthOfYear, int dayOfMonth) {

    String date = "You picked the following date: "+year+"/"+(++monthOfYear)+"/"+dayOfMonth;
    tvDateFrom.setText(date);

}

@Override
public void onTimeSet(RadialPickerLayout view, int hourOfDay, int minute, int second) {

    String hourString = hourOfDay < 10 ? "0"+hourOfDay : ""+hourOfDay;
    String minuteString = minute < 10 ? "0"+minute : ""+minute;
    String secondString = second < 10 ? "0"+second : ""+second;
    String time = "You picked the following time: "+hourString+"h"+minuteString+"m"+secondString+"s";
    tvTimeFrom.setText(time);
}

这是我的活动

public class DatePickerActivity extends AppCompatActivity {
private static final String TAG = "DatePickerActivity";
ViewPager viewPager;
PickerAdapter adapter;
String myString = "TEST";

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.date_fragment);
    String strObj = getIntent().getStringExtra("Location");
    GetParamsClass getParamsClass = new Gson().fromJson(strObj,GetParamsClass.class);

    adapter = new PickerAdapter(getFragmentManager());
    viewPager = (ViewPager) findViewById(R.id.pager);
    viewPager.setAdapter(adapter);

    setSupportActionBar((Toolbar) findViewById(R.id.toolbar));
    TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
    tabLayout.setupWithViewPager(viewPager);
    for(int i=0;i<adapter.getCount();i++) tabLayout.getTabAt(i).setText(adapter.getTitle(i));



}

public String getMyData() {
    return myString;
}

class PickerAdapter extends android.support.v13.app.FragmentPagerAdapter {
    private static final int NUM_PAGES = 2;
    Fragment fragmentOne;
    Fragment fragmentTwo;

    public PickerAdapter(FragmentManager fm) {
        super(fm);
        fragmentOne = new FragmentOne();
        fragmentTwo = new FragmentTwo();
    }

    @Override
    public int getCount() {
        return NUM_PAGES;
    }

    @Override
    public Fragment getItem(int position) {
        switch(position) {
            case 0:
                return fragmentOne;
            case 1:
            default:
                return fragmentTwo;
        }
    }

    public int getTitle(int position) {
        switch(position) {
            case 0:
                return R.string.tab_title_time;
            case 1:
            default:
                return R.string.tab_title_date;
        }
    }
}
}

编辑

public class DatePickerActivity extends AppCompatActivity implements  FragmentOne.OnDateTimeSelectedListener {
private static final String TAG = "DatePickerActivity";
ViewPager viewPager;
PickerAdapter adapter;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.date_fragment);

    adapter = new PickerAdapter(getFragmentManager(),this);
    viewPager = (ViewPager) findViewById(R.id.pager);
    viewPager.setAdapter(adapter);

    setSupportActionBar((Toolbar) findViewById(R.id.toolbar));
    TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
    tabLayout.setupWithViewPager(viewPager);
    for(int i=0;i<adapter.getCount();i++) tabLayout.getTabAt(i).setText(adapter.getTitle(i));
}

@Override
public void onDateTimeSelected(String date) {
    Log.d(TAG, "onDateTimeSelected: "+ date);
}

class PickerAdapter extends android.support.v13.app.FragmentPagerAdapter {
    private static final int NUM_PAGES = 2;
    Fragment fragmentOne;
    Fragment fragmentTwo;

    public PickerAdapter(FragmentManager fm,DatePickerActivity activity) {
        super(fm);
        fragmentOne = new FragmentOne();
        fragmentTwo = new FragmentTwo();
        fragmentOne.setOnDateTimeSelectedListener(activity);//THIS LINE GIVES ERROR

    }

    @Override
    public int getCount() {
        return NUM_PAGES;
    }

    @Override
    public Fragment getItem(int position) {
        switch(position) {
            case 0:
                return fragmentOne;
            case 1:
            default:
                return fragmentTwo;
        }
    }

    public int getTitle(int position) {
        switch(position) {
            case 0:
                return R.string.tab_title_time;
            case 1:
            default:
                return R.string.tab_title_date;
        }
    }
}

片段一

public class FragmentOne extends DialogFragment implements DatePickerDialog.OnDateSetListener,TimePickerDialog.OnTimeSetListener {

Button timeButtonFrom ;
Button dateButtonFrom;
TextView tvDateFrom ;
TextView tvTimeFrom ;


public interface OnDateTimeSelectedListener{
    void onDateTimeSelected(String date);
}



private OnDateTimeSelectedListener onDateTimeSelectedListener;

public void setOnDateTimeSelectedListener(OnDateTimeSelectedListener onDateTimeSelectedListener){
    this.onDateTimeSelectedListener = onDateTimeSelectedListener;
}

public OnDateTimeSelectedListener getOnDateTimeSelectedListener(){
    return onDateTimeSelectedListener;
}




public FragmentOne(){}

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

    //FROM SIDE
    timeButtonFrom = (Button)view.findViewById(R.id.time_button);
    dateButtonFrom = (Button)view.findViewById(R.id.date_button);
    tvDateFrom = (TextView)view.findViewById(R.id.time_textview);
    tvTimeFrom = (TextView)view.findViewById(R.id.date_textview);



    timeButtonFrom.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Calendar now = Calendar.getInstance();
            // TimePickerDialog tpd = TimePickerDialog.newInstance(
            TimePickerDialog tpd = TimePickerDialog.newInstance(
                    FragmentOne.this,
                    now.get(Calendar.HOUR_OF_DAY),
                    now.get(Calendar.MINUTE),true);//24H Enable, If 12 set false
            tpd.setThemeDark(true);
            tpd.enableMinutes(true);
            tpd.setTitle("Choose Time");
            tpd.setTimeInterval(1,15);//setTimeInterval to 1H and 15Min


            tpd.setOnCancelListener(new DialogInterface.OnCancelListener() {
                @Override
                public void onCancel(DialogInterface dialogInterface) {
                    Log.d("TimePicker", "Dialog was cancelled");
                }
            });

            tpd.show(getFragmentManager(), "ChooseTimeFrom");
        }
    });// end Button Listener FROM

    dateButtonFrom.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Calendar now = Calendar.getInstance();
            DatePickerDialog dpd = DatePickerDialog.newInstance(
                    FragmentOne.this,
                    now.get(Calendar.YEAR),
                    now.get(Calendar.MONTH),
                    now.get(Calendar.DAY_OF_MONTH)
            );
            dpd.setThemeDark(true);
            dpd.showYearPickerFirst(true);
            dpd.setTitle("Choose Date");
            dpd.show(getFragmentManager(), "ChooseDateFrom");
        }
    });//END DATEBUTTONFROM




    return  view;

}//END ONCREATEVIEW

@Override
public void onResume() {
    super.onResume();
    DatePickerDialog dpd = (DatePickerDialog) getFragmentManager().findFragmentByTag("ChooseDateFrom");
    if(dpd != null) dpd.setOnDateSetListener(this);
    TimePickerDialog tpd = (TimePickerDialog) getFragmentManager().findFragmentByTag("ChooseTimeFrom");
    if(tpd != null) tpd.setOnTimeSetListener(this);

}



@Override
public void onDateSet(DatePickerDialog view, int year, int monthOfYear, int dayOfMonth) {

    String date = "You picked the following date: "+year+"/"+(++monthOfYear)+"/"+dayOfMonth;
    tvDateFrom.setText(date);

    if(tvTimeFrom != null && tvTimeFrom.getText() != null && !tvTimeFrom.getText().toString().equals("")){

        String dateTimeString = date + tvTimeFrom.getText().toString();
        onDateTimeSelectedListener.onDateTimeSelected(dateTimeString);
    }


}

@Override
public void onTimeSet(RadialPickerLayout view, int hourOfDay, int minute, int second) {

    String hourString = hourOfDay < 10 ? "0"+hourOfDay : ""+hourOfDay;
    String minuteString = minute < 10 ? "0"+minute : ""+minute;
    String secondString = second < 10 ? "0"+second : ""+second;
    String time = "You picked the following time: "+hourString+"h"+minuteString+"m"+secondString+"s";
    tvTimeFrom.setText(time);

    if(tvDateFrom != null && tvDateFrom.getText() != null && !tvDateFrom.getText().toString().equals("")){

        String dateTimeString = tvDateFrom.getText().toString() + time;
        onDateTimeSelectedListener.onDateTimeSelected(dateTimeString);
    }




}
}//END FRAGMENT CLASS

【问题讨论】:

  • 我没有看到你的代码,但是你的问题的标题我可以说你可以使用接口将一些数据发送回活动。
  • 你有同样的例子吗?
  • 你可以使用接口或本地广播进行通信
  • 在activity和fragment之间传递数据有多种方式。在您的情况下,一个简单的解决方案是在您想要设置选取值的活动类中创建 Globar 变量。在您的片段类中调用 getActivity() 方法,该方法将引用您的活动(从 Activity 转换到您的 Activity 类),并使用该方法访问之前声明的全局变量并为其设置值。接口方法比这种方法干净得多。

标签: android android-fragments


【解决方案1】:

试试这个, 在 FragmentOne 创建一个接口说

public interface OnDateTimeSelectedListener{
    void onDateTimeSelected(String date, S)
}



private OnDateTimeSelectedListener onDateTimeSelectedListener;

public void setOnDateTimeSelectedListener(OnDateTimeSelectedListener onDateTimeSelectedListener){
        this.onDateTimeSelectedListener = onDateTimeSelectedListener;
}

public OnDateTimeSelectedListener getOnDateTimeSelectedListener(){
        return onDateTimeSelectedListener;
}

在 onDateSet(...) 方法中检查是否已经选择了时间,如果是则调用回调

if(tvTimeFrom != null && tvTimeFrom.getText() != null && !tvTimeFrom.getText().toString().trim.equals("")){

    String dateTimeString = date + tvTimeFrom.getText().toString();
    onDateTimeSelectedListener.onDateTimeSelected(dateTimeString);
}

在 onTimeSet 方法中检查是否已经选择了时间,如果是则调用回调

if(tvDateFrom != null && tvDateFrom.getText() != null && !tvDateFrom.getText().toString().trim.equals("")){

    String dateTimeString = tvDateFrom.getText().toString() + time;
    onDateTimeSelectedListener.onDateTimeSelected(dateTimeString);
}

在 DatePickerActivity 中

更新这一行:

public class DatePickerActivity extends AppCompatActivity implements FragmentOne.OnDateTimeSelectedListener{


 // update inside

更新:

   adapter = new PickerAdapter(getFragmentManager(), this);
  ....     

public PickerAdapter(FragmentManager fm) 

constructor 更新构造函数并尝试设置监听器

更新

public PickerAdapter(FragmentManager fm, DatePickerActivity activity) {
        super(fm);
        fragmentOne = new FragmentOne();
        fragmentTwo = new FragmentTwo();
fragmentOne.setOnDateTimeSelectedListener(activity);
    }

并覆盖

void onDateTimeSelected(String datetimeString){
    //You will get DatetimeString here
    //use it

}

更新

删除出错的那一行并添加这两种方法并尝试

@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);
    // This makes sure that the container activity has implemented
    // the callback interface. If not, it throws an exception
    try {
          onDateTimeSelectedListener = (OnDateTimeSelectedListener) activity;

    } catch (ClassCastException e) {
        throw new ClassCastException(activity.toString()
                + " must implement OnHeadlineSelectedListener");
    }

}

@Override
public void onDetach(){
super.onDetach();    
onDateTimeSelectedListener = null

}

参考:Communicating with Other Fragments

【讨论】:

    【解决方案2】:
    Class Activity1
    {
    private String pickedDateValue;
    
    public setPickedDateValue(string val)
    {
    pickedDateValue = val;
    }
    }
    
    Class Fragment1
    {
      Activity1 act1 = (Activity1)getActivity();
       act1.setPickedDateValue(pickedval)
    }
    

    //其中pickval是从日期/时间选择器中选择的值

    【讨论】:

      【解决方案3】:

      如果它的父 Activity 则在您的 Fragment 中添加此代码。

      ((DatePickerActivity)getBaseActivity()).saveData();
      

      您可以调用saveData() 函数或将数据作为Bundle 对象传递。在 Activity 中添加保存数据。

      【讨论】:

      • 你有例子吗?谢谢
      【解决方案4】:

      你应该使用回调接口在 Fragment 和它的宿主 Activity 之间进行交互。例如:

      1. 在接口中声明,并带有数据,您需要将其作为参数发送给Activity

        public interface Callback {
            void onDataPicked(Data data);
        }
        
      2. 您的活动应该实现此接口。在覆盖的方法中编写自己的代码。例如:

        @Override
            public void onDataPicked(Data data) {
            Intent intent = new Intent(this, AnotherActivity.class);
            intent.putExtra("some_data", data);
            startActivity(intent);
        }
        
      3. 在 Fragment 的 onAttach 方法中声明 Callback 实例并获取宿主 Activity 的链接。

        private Callback mCallback;
        
        @Override
        public void onAttach(Context context) {
            super.onAttach(context);
            if(context instanceof Callback){
                mCallback = (Callback) context;
            }
        }
        
      4. 最后,当你的数据准备好调用 Calback 实例的方法 ant 时,它将在 Activity 中运行

        @Override
        public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
            super.onViewCreated(view, savedInstanceState);
        
        
            Button button = (Button) view.findViewById(R.id.button);
            button.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    mCallback.onDataPicked(new Data());
                }
            });
        }
        
      5. 不要忘记在 Fragment 的 onDetach() 方法中将 mCallback 设置为 null 以避免内存泄漏

        @Override
        public void onDetach() {
            super.onDetach();
            mCallback = null;
        }
        

      【讨论】:

      • 我会尽快尝试。非常感谢
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多