简体   繁体   English

如何从Web服务将ViewPager中的片段添加到TabLayout?

[英]How to add Fragments in ViewPager to TabLayout from a web service?

I'm trying to add tabs to my TabLayout-ViewPager-Fragment based application dynamically.The TabLayout uses a custom view with an ImageView on top of a TextView . 我试图动态地将选项卡添加到基于TabLayout-ViewPager-Fragment的应用程序中TabLayout使用自定义视图以及TextView顶部的ImageView

What I want now is to add tabs according to the number of JSONObjects in my JSONArray created from a PHP/MySQL web service. 我现在想要的是根据从PHP / MySQL Web服务创建的JSONArrayJSONObjects数量添加选项卡。 I tried the method below in my PagerAdapter but it throws: 我在我的PagerAdapter尝试了以下方法,但它抛出:

java.lang.IllegalStateException: Can't change tag of fragment TstFrag{df80bc8 #0 id=0x7f080157 android:switcher:2131231063:0}: was android:switcher:2131231063:0 now android:switcher:2131231063:1 . java.lang.IllegalStateException: Can't change tag of fragment TstFrag{df80bc8 #0 id=0x7f080157 android:switcher:2131231063:0}: was android:switcher:2131231063:0 now android:switcher:2131231063:1

The method is as in my Adapter below 方法如下面的我的适配器

public class FrgAdapter extends FragmentStatePagerAdapter {
private List<Fragment> mFragmentList = new ArrayList<>();
private List<String> mFragmentTitleList = new ArrayList<>();

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

public FrgAdapter(FragmentManager fm, List<Fragment> mFragmentList, List<String> mFragmentTitleList) {
    super(fm);
    this.mFragmentList = mFragmentList;
    this.mFragmentTitleList = mFragmentTitleList;

}

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

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

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

public void insertFromJSONObject(JSONObject jsonObject, Fragment fragment, CircularImageView imageView, TextView textView) throws JSONException {
    JSONArray dataArray = jsonObject.getJSONArray("data");

    for (int i = 0; i < dataArray.length(); i++) {
        JSONObject sectionObj = (JSONObject) dataArray.get(i);

        JSONArray sectionsArray = sectionObj.getJSONArray("section");

        for (int j = 0; j < sectionsArray.length(); j++) {
            JSONObject obj = (JSONObject) sectionsArray.get(j);
            Picasso.get().load(obj.getString("imag")).into(imageView);
            mFragmentList.add(fragment);
            mFragmentTitleList.add(obj.getString("name"));
            textView.setText(obj.getString("name"));
            notifyDataSetChanged();
        }
    }
}

@Override
public CharSequence getPageTitle(int position) {
    return null;
}}

Here is where the method is called in my activity to add the fragments: 这是在我的活动中调用该方法以添加片段的位置:

private void setUpViewPager(ViewPager viewPager, View view) {
    adapter = new FrgAdapter(getSupportFragmentManager());
    /*adapter.addFragment(new MleFrag(), "Men");
    adapter.addFragment(new FmlFrag(), "Women");
    adapter.addFragment(new ChdFrag(), "Children");
    adapter.addFragment(new AceFrag(), "Accessories");
    */
    String url = "https://44091ee6.ngrok.io/Glam/men.json";
    AndroidNetworking.get(url)
            .setPriority(Priority.MEDIUM)
            .build()
            .getAsJSONObject(new JSONObjectRequestListener() {
                @Override
                public void onResponse(JSONObject response) {
                    try {
                        adapter.insertFromJSONObject(response, new TstFrag(), view.findViewById(R.id.circularImageView), view.findViewById(R.id.text_header));
                        adapter.notifyDataSetChanged();
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                }

                @Override
                public void onError(ANError anError) {
                    Toast.makeText(getApplicationContext(), anError.toString(), Toast.LENGTH_LONG).show();
                }
            });
    adapter.notifyDataSetChanged();
    viewPager.setAdapter(adapter);
}

and here is my Fragment . 这是我的Fragment In my mind I want to reuse this one Fragment for each of the times I will be requiring one. 在我的脑海中,我想在需要的每一次重复使用这个Fragment

public class TstFrag extends Fragment {

public TstFrag() {

}

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

@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    return inflater.inflate(R.layout.layout_cht, container, false);
}}

You may try this: 您可以尝试以下方法:

adapter.insertFromJSONObject(response, view.findViewById(R.id.circularImageView), view.findViewById(R.id.text_header));
adapter.notifyDataSetChanged();

and

public void insertFromJSONObject(JSONObject jsonObject, CircularImageView imageView, TextView textView) throws JSONException {
    JSONArray dataArray = jsonObject.getJSONArray("data");

    for (int i = 0; i < dataArray.length(); i++) {
        JSONObject sectionObj = (JSONObject) dataArray.get(i);

        JSONArray sectionsArray = sectionObj.getJSONArray("section");

        for (int j = 0; j < sectionsArray.length(); j++) {
            JSONObject obj = (JSONObject) sectionsArray.get(j);

            Picasso.get().load(obj.getString("imag")).into(imageView);
            mFragmentList.add(new TstFrag());
            textView.setText(obj.getString("name"));
            //mFragmentTitleList.add(obj.getString("name"));
            notifyDataSetChanged();
        }
    }
}

The basic idea here is to create a new instance of TstFrag for each entry of the FrgAdapter . 这里的基本想法是创建一个新实例TstFrag对的每个条目FrgAdapter

Consider NOT to add fragments to viewPager manually but just implement getItem && instantiateItem methods on viewPager adapter. 考虑以片段添加到viewPager手动只是实现getItem && instantiateItem viewPager适配器上的方法。 Then viewPager will control the instantiation of new TstFrag or just reuse created one. 然后,viewPager将控制新TstFraginstantiation ,或仅重用创建的 TstFrag Check this answer for complete adapter . 检查此答案以获取完整的适配器

@Override
public Fragment getItem(final int pos) {
    return TstFrag.getInstance(dataList.get(pos));
}


@NonNull
@Override
public Object instantiateItem(ViewGroup container, int position) {
    Fragment fragment = (Fragment) super.instantiateItem(container, position);
    registeredFragments.put(position, fragment);
    return fragment;
}

@Override
public void destroyItem(ViewGroup container, int position, Object object) {
    registeredFragments.remove(position);
    super.destroyItem(container, position, object);
}

Update 更新资料

public class DataModel implements Serializable{
  private String name;
  private String image;
  // GETTER && SETTER 
}

Replace 更换

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

With

 private List<DataModel> dataList = new ArrayList<>();

insertFromJSONObject insertFromJSONObject

    dataList.clear();
    for (int j = 0; j < sectionsArray.length(); j++) {
        JSONObject obj = (JSONObject) sectionsArray.get(j);
        final DataModel model = new DataModel();
        model.setName(obj.getString("name"));
        model.setImage(obj.getString("imag"));
        // Picasso.get().load(obj.getString("imag")).into(imageView);
        // No need to load image here just fetch for cache if you want.
        Picasso.get().load(model.getImage()).fetch();
        // mFragmentList.add(fragment); // no need handle adding fragment here as mentioned above.
        dataList.add(dataModel);
        // textView.setText(obj.getString("name")); // It's not good to update UI here but update there with fragment on create called mention below.
        // notifyDataSetChanged(); DON'T call this inside the loop but after finish your stuff.
    }
    // Just notify here...
    notifyDataSetChanged();

TstFrag TstFrag

public class TstFrag extends Fragment {
 private DataModel model;
public TstFrag() {

}

public static TstFrag getInstance(DataModel model){
  TstFrag fragment = new TstFrag();
  Bundle bundle = new Bundle();
  bundle.putSerializable("mData", model);
  fragment.setArguments(bundle);
  return fragment;
} 

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    model = (DataModel)getArguments().getSerializable("mData");
}

@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    final View rootView =  inflater.inflate(R.layout.layout_cht, container, false);
    // findViewById() for imageView and nameTextView 
     Picasso.get().load(model.getImage()).into(imageView);
     nameTextView.setText(model.getName());

}}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何使用 tabLayout 在 ViewPager 中显示片段? - How to show fragments in ViewPager with tabLayout? 如何更新 Tablayout 中的片段? (Viewpager2, FragmentStateAdapter) - How to update Fragments in Tablayout? (Viewpager2, FragmentStateAdapter) 使用 TabLayout 和 ViewPager 的片段 - Fragments with TabLayout and ViewPager 带有TabLayout的ViewPager不显示片段 - ViewPager with TabLayout not displaying the fragments 如何从getView在ViewPager中添加片段 - How to add Fragments in ViewPager from getView 从第二个Fragment的recyclerView中选择项目时如何切换到第一个Fragment? 两个片段都在带有 viewPager2 的 tablayout 中 - How to switch to the first fragment when selecting an item from the recyclerView of second Fragment? Both fragments are in tablayout with viewPager2 Android-TabLayout和ViewPager&gt;片段&gt; OnListFragmentInteractionListener - Android - TabLayout & ViewPager > Fragments > OnListFragmentInteractionListener 使ViewPager TabLayout片段可滚动 - Making viewpager tablayout fragments scrollable 如何在ViewPager中添加片段 - How to add fragments inside viewpager 使用ViewPager将DrawerLayout添加到TabLayout - Add DrawerLayout to TabLayout with ViewPager
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM