代码之家  ›  专栏  ›  技术社区  ›  Kennedy Kambo

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

  •  0
  • Kennedy Kambo  · 技术社区  · 7 年前

    我正在尝试将标签添加到 TabLayout-ViewPager-Fragment 动态地基于应用程序 TabLayout 使用自定义视图 ImageView 在一个 TextView .

    我现在想要的是根据 JSONObjects 在我的 JSONArray 从PHP/MySQL web服务创建。我尝试了下面的方法 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 .

    方法如下所示

    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;
    }}
    

    下面是在我的活动中调用方法以添加片段的位置:

    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);
    }
    

    这是我的 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);
    }}
    
    2 回复  |  直到 6 年前
        1
  •  1
  •   Lino    7 年前

    你可以试试这个:

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

    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();
            }
        }
    }
    

    这里的基本思想是创建 TstFrag 对于 FrgAdapter .

        2
  •  1
  •   Khaled Lela    7 年前

    考虑 不是 添加片段到 viewPager 手动但仅执行 getItem &amp; instantiateItem 方法。然后viewPager将控制 instantiation 新的 TstFrag 或者只是 重新使用已创建 一个。 检查这个 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);
    }
    

    更新

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

    替换

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

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

    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公司

    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());
    
    }}