【问题标题】:Java Android - Send data from activity to fragmentJava Android - 将数据从活动发送到片段
【发布时间】:2017-12-16 08:51:58
【问题描述】:

过去一天,我一直试图弄清楚如何将数据从Activity 传递到Fragment,但还没有走多远。我知道如何将数据从Fragment 传递到Activity。我认为我不能针对我的情况使用捆绑包,因为我的 Fragment 已经创建,并且需要继续收听 Activity 进行任何更改。我也尝试过创建一个界面,但我得到了一些循环错误。将数据从 Fragment 传递到 Activity 对我来说非常容易,我觉得我在考虑如何将数据从 Activity 传递回 Fragment

这是我正在尝试做的一个简单版本。 Activity 位于顶部,底部按钮来自 Fragment 布局。

当我从MainActivity单击 BTN1 时,我希望按钮 TESTBTN 1A 变为红色并存储 i = 1。然后按钮 TESTBTN 1B 将变为绿色且 i = 2。按钮 TESTBTN 1C 将更改变为蓝色并且 i = 3。当单击 NEXT FRAGMENT 时,它会将 Fragment 带到下一个(希望不会丢失按钮颜色更改)。

这是我MainActivity的主要部分

public class MainActivity extends AppCompatActivity implements Main2Activity.OnDataPass{
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    mSectionsPageAdapter = new SectionsPageAdapter(getSupportFragmentManager());
    mViewPager = (ViewPager) findViewById(R.id.container);
    setupViewPager(mViewPager);
}


public void onClickBtn1(View v){
    //need to send data over to fragment1 to be stored and to change color
}

public void onClickBtn2(View v){
    //need to send data over to fragment1 to be stored and to change color
}

public void onClickBtn3(View v){
    //need to send data over to fragment1 to be stored and to change color
}

public void onClickBtn4(View v){
    //go to next fragment
}

//used for when fragment passes data to activity
@Override
public void onDataPass(String data) {
    Log.d("LOG", "passed data: " + data);
}

private void setupViewPager(ViewPager viewPager) {
    SectionsPageAdapter adapter = new SectionsPageAdapter(getSupportFragmentManager());
    adapter.addFragment(new Main2Activity(), "TAB1");
    adapter.addFragment(new Main3Activity(), "TAB2");
    adapter.addFragment(new Main4Activity(), "TAB3");
    viewPager.setAdapter(adapter);

这是我的Fragment

public class Main2Activity extends Fragment implements View.OnClickListener  {
int i;
Button btnTESTa, btnTESTb, btnTESTc;     
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,  Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.activity_main2,container,false);
    btnTESTa = view.findViewById(R.id.btnTESTa);
    btnTESTb = view.findViewById(R.id.btnTESTb);
    btnTESTc = view.findViewById(R.id.btnTESTc);

    btnTESTa.setOnClickListener(this);
    btnTESTb.setOnClickListener(this);
    btnTESTc.setOnClickListener(this);

    return view;
}

//NEED TO CREATE A WAY TO LISTEN FOR DATA SENT OVER FROM ACTIVITY TO CHANGE BUTTON COLORS AND STORE INT I VALUE

@Override
public void onClick(View v) {
    switch (v.getId()) {
        case R.id.btnTESTa:
            i = 0;
            break;
        case R.id.btnTESTb:
            i = 1;
            break;
        case R.id.btnTESTc:
            i = 2;
            break;
    }

    passData(String.valueOf(i));
}

//used to pass data over from fragment to activity
OnDataPass dataPasser;

public interface OnDataPass {
    void onDataPass(String data);
}

@Override
public void onAttach(Context a) {
    super.onAttach(a);
    dataPasser = (OnDataPass) a;
}

public void passData(String data) {
    dataPasser.onDataPass(data);
}

这是我的 SectionsPageAdapter 公共类 SectionsPageAdapter 扩展 FragmentPagerAdapter {

private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();

public void addFragment(Fragment fragment, String title) {
    mFragmentList.add(fragment);
    mFragmentTitleList.add(title);
}

public SectionsPageAdapter(FragmentManager fm) {
    super(fm);
}

@Override
public CharSequence getPageTitle(int position) {
    return mFragmentTitleList.get(position);
}

@Override
public Fragment getItem(int position) {
    return mFragmentList.get(position);
}

@Override
public int getCount() {
    return mFragmentList.size();
}

非常感谢任何有关如何实现将数据从Activity 发送到Fragment 以更改按钮颜色的帮助,谢谢!

【问题讨论】:

  • Activity 代码中的 Fragment 实例在哪里?为什么不能只调用该片段上的方法?暂时删除 ViewPager。这只是复杂的事情
  • 您可以在片段中创建一个公共方法并使用您创建的片段实例调用它。
  • 顺便说一下,Main2Activity extends Fragment 不是 Activity。如果您希望其他人理解代码,请修正您的类命名约定
  • 你为什么要把这个简单的任务复杂化,只需使用一个界面并为相应的按钮单击传递 id 并相应地更改片段内的颜色
  • @cricket_007 刚刚添加了片段实例......或者至少我认为它是。抱歉,刚开始学习 Fragments,对一切还有些迷茫

标签: java android android-fragments android-activity android-fragmentactivity


【解决方案1】:

您的代码中的问题是 OnDataPass 实例必须在您的 Activity 而不是 Fragment 中创建,因为您希望将数据从 Activity 传递到 Fragment 而不是 Fragment 到 Activity。

所以 Activity 和 Fragment 类的示例代码块将是这样的。

public class MainActivity extends AppCompatActivity implements MyFragment.OnDataPass{

          MyFragment fragmentInstance;



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

              fragmentInstance = new MyFragment();
          }

          private void loadMyFragment(){
             fragmentInstance = new MyFragment();
             //code to load fragment

          }

      public void passData(String data) {
         if (fragmentInstance != null) fragmentInstance.dataFromActivity(data);
      }

      @Override
          public void onDataPass(String data){
             //handle data and do the needful. Instead of String you can even use bundle here.
          }
    }

正如我在评论中提到的,创建了一个名为 dataFromActivity 的公共方法,您可以从 Activity 类调用该方法,将数据从您的 Activity 传递到 Fragment。

public class MyFragment extends Fragment {
       OnDataPass dataPasser;

       public interface OnDataPass {
            void onDataPass(String data);
       }

    @Override
    public void onAttach(Context a) {
        super.onAttach(a);
        dataPasser = (OnDataPass) a;
    }

    @Override
        public void onDetach() {
            super.onDetach();

            dataPasser = null;
    }

    public void passData(String data) {
        if (dataPasser != null) dataPasser.onDataPass(data);
    }

        //method called from Activity
        public void dataFromActivity(String data){
            //handle data and do the needful. Instead of String you can even use bundle here.
        }
    }

Fragment 将使用OnDataPass 接口将数据从Fragment 发送到Activity。

【讨论】:

  • 我确实想将数据从 Fragment 传递到 Activity。但我也想将数据从 Activity 传递到 Fragment。似乎是一个非常简单的任务,但我想不通
  • 检查修改后的代码,现在你可以同时进行,即可以将数据从 Activity 传递到 Fragment 和 Fragment 到 Activity。
【解决方案2】:

在 Main2Activity 中添加 setter 方法,如下所示

 public void setDataPasser(OnDataPass dataPasser) {
    this.dataPasser = dataPasser;
}

然后在MainActivity中调用这个setter方法。 然后在您的 MainActivity 中更新以下方法:

private void setupViewPager(ViewPager viewPager) {
SectionsPageAdapter adapter = new SectionsPageAdapter(getSupportFragmentManager());
Main2Activity fragment = new Main2Activity();
fragment.setListener(this);
adapter.addFragment(fragment, "TAB1");
viewPager.setAdapter(adapter);

【讨论】:

    【解决方案3】:

    activitiesfragments 之间有多种通信方式,但是,您给它们的使用取决于您的应用程序的要求。
    如果Fragment初始化需要数据,可以使用每个fragmentnewInstance方法作为参数传递。
    如果您需要在runtime 中传递数据,则需要使用interface,它将使用活动Context 在每个片段的onAttach 方法中进行初始化,并在每次片段被销毁时变为空。
    要总结第二个选项,您需要:

    1. 声明一个interface,很可能在您正在处理的fragment 中。
    2. 声明一个interface类型的全局变量。
    3. 在片段的onAttach方法中初始化变量。
    4. onDestroy 方法中使变量无效。
    5. 在你想要的按钮中调用接口方法。
    6. activity中实现interface并处理回调方法。

    【讨论】:

      【解决方案4】:

      试试这个.....

      Main2Activity.java

       public class Main2Activity extends Fragment implements View.OnClickListener  {
       .......
      
         //method to change button background at run time.
         public void changeButtonColor(View view){
            switch(view.getId()){
            case R.id.btnTESTa:
                btnTESTa.setBackgroundColor(Color.RED)
                 i = 1;
                break;
            case R.id. btnTESTb:
                btnTESTb.setBackgroundColor(Color.GREEN)
                 i = 2;
                break;
            case R.id. btnTESTc:
                btnTESTc.setBackgroundColor(Color.BLUE)
                 i = 3;
                break;
            }
         }
       ........
       }
      

      MainActivity.java

       public class MainActivity extends AppCompatActivity implements Main2Activity.OnDataPass{
      
        .........
      
        private Main2Activity fragment2;
        private Main3Activity fragment3;
        private Main4Activity fragment4;
      
        public void onClickBtn1(View v){
            fragment2.changeButtonColor(v);
        }
      
        public void onClickBtn2(View v){
            fragment3.changeButtonColor(v);
        }
      
        public void onClickBtn3(View v){
            fragment4.changeButtonColor(v);
        }
      
        public void onClickBtn4(View v){
             //fragment transaction code here
        }
      
        private void setupViewPager(ViewPager viewPager) {
            .......
            fragment2 = new Main2Activity();
            fragment3 = new Main3Activity();
            fragment4 = new Main4Activity();
      
              adapter.addFragment(fragment2, "TAB1");
              adapter.addFragment(fragment3, "TAB2");
              adapter.addFragment(fragment4, "TAB3");
              .......
         }
         .......
       }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-09-26
        • 1970-01-01
        • 2014-09-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多