android - 在ViewPager中将数据从Activity传递给Fragment

时间:2017-09-05 08:20:24

标签: android android-viewpager fragment listener

我有一个简单的Activity,其中包含TabLayout,ViewPager和2个片段。这是我的活动:

public class ManagementCompanyOverviewActivity extends BaseActivity implements ManagementCompanyOverviewView {

    private ManagementCompanyVPAdapter mVPAdapter;
    private TabLayout mTLContent;
    private ViewPager mVPContent;

    @InjectPresenter
    ManagementCompanyPresenter mPresenter;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_management_company);

        mVPAdapter = new ManagementCompanyVPAdapter(getSupportFragmentManager());

        mTLContent = (TabLayout) findViewById(R.id.tl_company_content);

        mVPContent = (ViewPager) findViewById(R.id.vp_company_content);
        mVPContent.setAdapter(mVPAdapter);
        mTLContent.setupWithViewPager(mVPContent);
    }

    @Override
    public void onAboutCompanyInfoReceivedFromServer(AboutCompanyViewModel model) {

    }

Activity有一个Presenter(我使用Moxy),Presenter发送请求,获得答案,创建JavaObject(视图模型),并使用getViewState()将此模型传递给activity。我需要将此模型从Activity传递给我的一个片段。

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

    View view = inflater.inflate(R.layout.fragment_about_company, container, false);

    mTVName = (TextView) view.findViewById(R.id.tv_company_name);
    mTVDirector = (TextView) view.findViewById(R.id.tv_company_director);
    mTVWebsite = (TextView) view.findViewById(R.id.tv_company_website);
    mTVEmail = (TextView) view.findViewById(R.id.tv_company_email);
    mTVPhone = (TextView) view.findViewById(R.id.tv_company_phone);
    mTVSchedule = (TextView) view.findViewById(R.id.tv_company_schedule);
    mTVAddress = (TextView) view.findViewById(R.id.tv_company_address);

    return view;
}

这个片段有一些TextViews来显示我模型的信息。如何通过这个模型?如果我知道它应该创造一个倾听者,但是如何?我不完全理解如何与他们合作。

7 个答案:

答案 0 :(得分:11)

好的,我做到了。

1步:我在我的Activity和setter中为它创建了公共接口:

private OnAboutDataReceivedListener mAboutDataListener;

public interface OnAboutDataReceivedListener {
        void onDataReceived(AboutCompanyViewModel model);
    }

public void setAboutDataListener(OnAboutDataReceivedListener listener) {
    this.mAboutDataListener = listener;
}

2步:我在Fragment中实现了这个接口并设置了listener:

public class AboutCompanyFragment extends BaseFragment implements ManagementCompanyOverviewActivity.OnAboutDataReceivedListener

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

            mActivity = (ManagementCompanyOverviewActivity) getActivity();
            mActivity.setAboutDataListener(this);
        }

3步:我重写了界面的方法:

@Override
    public void onDataReceived(AboutCompanyViewModel model) {
        mPBName.setVisibility(View.INVISIBLE);
        mPBDirector.setVisibility(View.INVISIBLE);
        mPBWebsite.setVisibility(View.INVISIBLE);
        mPBEmail.setVisibility(View.INVISIBLE);
        mPBPhone.setVisibility(View.INVISIBLE);
        mPBSchedule.setVisibility(View.INVISIBLE);
        mPBAddress.setVisibility(View.INVISIBLE);

        mTVName.setVisibility(View.VISIBLE);
        mTVDirector.setVisibility(View.VISIBLE);
        mTVWebsite.setVisibility(View.VISIBLE);
        mTVEmail.setVisibility(View.VISIBLE);
        mTVPhone.setVisibility(View.VISIBLE);
        mTVSchedule.setVisibility(View.VISIBLE);
        mTVAddress.setVisibility(View.VISIBLE);

        mTVName.setText(model.getCompanyName());
        mTVDirector.setText(model.getDirectorName());
        mTVWebsite.setText(model.getWebsite());
        mTVEmail.setText(model.getEmail());
        mTVPhone.setText(model.getPhone());
        mTVSchedule.setText(model.getWorkTime());
        mTVAddress.setText(model.getAddress());
    }

就是这样。

答案 1 :(得分:2)

试试这个 在活动中

public String sendData() {
        return YOUR_STRING;
    }

在片段中

YOUR_ACTIVITY activity = (YOUR_ACTIVITY) getActivity();
String getData = activity.SendData();

答案 2 :(得分:2)

  

您可以在片段中使用newInstance方法:

public static MyFragment newInstance(String parameter) {

        Bundle args = new Bundle();
        args.putString("parameter", parameter);
        SfCategoryFragment fragment = new SfCategoryFragment();
        fragment.setArguments(args);
        return fragment;
    }

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

        if (getArguments() != null) {
            parameter = getArguments().getString("parameter");
        }
    }
  

在你的活动中:

而不是new MyFragment()使用MyFragment.newInstance("yourParam");

答案 3 :(得分:1)

片段

class SampleFragment : Fragment(), BaseFragmentInteraction {
    override fun updateFragmentData(data: String) {
        Toast.makeText(activity!!, data, Toast.LENGTH_SHORT).show()
    }
}

接口

interface BaseFragmentInteraction {
    fun updateFragmentData(data: String)
}

活动:

view_pager.addOnPageChangeListener(object : ViewPager.OnPageChangeListener {

        override fun onPageSelected(position: Int) {
            val fragmentItem = (view_pager.adapter as FragmentPagerAdapter).getItem(view_pager.currentItem)
            (fragmentItem as BaseFragmentInteraction).updateFragmentData("SomeData")
        }

        override fun onPageScrollStateChanged(state: Int) {}

        override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {}
    })

updateFragmetData方法将在当前选定的viewpager项目片段中调用。您还可以在updateFragmetData中添加标签参数,以确保可以调用正确的片段实例。如果需要,您可以在isVisible实现中调用updateFragmetData以确保该片段可见。

答案 4 :(得分:0)

您也可以在适配器的构造函数中接收要在片段中显示的数据,并在返回新片段之前设置参数

public class ViewPagerAdapter extends FragmentStatePagerAdapter {
private Weather weather;

ViewPagerAdapter(FragmentManager fm, Weather weather) {
    super(fm);
    this.weather = weather;
}

@Override
public Fragment getItem(int position) {
    switch (position) {
        case 0:
            Bundle bundle = new Bundle();
            WeatherFragment weatherFragment = new WeatherFragment();
            bundle.putParcelable("weather", weather);
            weatherFragment.setArguments(bundle);
            return weatherFragment;
        case 1:
            return new PoemFragment();
        default:
            return new EmptyFragment();
    }
}

答案 5 :(得分:0)

来自Activity或ViewPager

Bundle bundle = new Bundle();
bundle.putParcelable(Keys.KEY_ITEM, cardResult);
CardItemFragment cardItemFragment = new CardItemFragment();
cardItemFragment.setArguments(bundle);

来自片段

@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
     getBundle();
}


private void getBundle() {
    bundle = getArguments();
    if (null != bundle) {
        if (bundle.containsKey(Keys.KEY_ITEM)) {
            cardResult = bundle.getParcelable(Keys.KEY_ITEM);
        }
    }
}

答案 6 :(得分:0)

我找到了一种将数据直接传递给片段或片段适配器的新方法

首先你做一个获取数据的getter方法假设你想获取用户名 你在活动中创建一个方法

public String getUsername(){
return username;
}

然后你像这样从片段和片段适配器调用这个方法

片段

(MainActivity) getActivity()).getUsername()

适配器

(MainActivity) context).getUsername()

这种方式还可以帮助您减少对数据库的请求次数