[英]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服务创建的JSONArray
的JSONObjects
数量添加选项卡。 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将控制新TstFrag
的instantiation
,或仅重用创建的 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.