有没有办法动态创建片段并使用相同的布局向它们显示数据?
Is there a way to dynamically create fragments and display data to them using the same layout?
我编写了从远程端点获取 JSON 对象的代码。对于这个问题,我传入了一个模拟对象,它是一个对象数组。
我的目标是解构对象并为数组的每个元素在 ViewPager 中创建一个片段。每个片段都应该显示它所代表的对象的 ID。
对象看起来像这样:
{'data':[{'id':1},{'id':2}]}
如果我取消注释 FragmentClass 中的代码,每个片段都会显示“test”。但是,如果我尝试根据通过参数传递的值设置文本,我 运行 会出现此错误:
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object android.os.Bundle.get(java.lang.String)' on a null object reference
FragmentClass 的代码是:
public class FragmentClass extends Fragment {
private TextView txtId;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = (ViewGroup) inflater.inflate(
R.layout.fragment_screen_slide, container, false);
txtId = (TextView) rootView.findViewById(R.id.txtId);
txtId.setText(getArguments().get("id").toString());
// txtId.setText("test");
return rootView;
}
}
ViewPager class、ScreenSliderPagerActivity 的代码是:
public class ScreenSliderPagerActivity extends FragmentActivity {
private ViewPager mPager;
private PagerAdapter pagerAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
Intent intent = getIntent();
String data = intent.getStringExtra("data");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_screen_slide);
// Instantiate a ViewPager and a PagerAdapter.
mPager = (ViewPager) findViewById(R.id.pager);
pagerAdapter = new ScreenSlidePagerAdapter(getSupportFragmentManager(), data);
mPager.setAdapter(pagerAdapter);
}
@Override
public void onBackPressed() {
if (mPager.getCurrentItem() == 0) {
// If the user is currently looking at the first step, allow the system to handle the
// Back button. This calls finish() on this activity and pops the back stack.
super.onBackPressed();
} else {
// Otherwise, select the previous step.
mPager.setCurrentItem(mPager.getCurrentItem() - 1);
}
}
private class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter {
public int NUM_PAGES; //making this a public variable within the inner class allows me to dynamically change the number of fragments created. In this instance, 2 will be created, one for each element of the array.
public ScreenSlidePagerAdapter(FragmentManager fm, String data) {
super(fm);
try {
JSONObject json = new JSONObject(data);
JSONArray jsonArray = json.getJSONArray("data");
NUM_PAGES = jsonArray.length();
Log.d("NUM_PAGES", String.valueOf(NUM_PAGES)); //2
FragmentTransaction ft = fm.beginTransaction();
Bundle args = new Bundle();
// I think the problem is something in the loop, but I cannot seem to figure another way to do this.
for (int i = 0; i < NUM_PAGES; i++){
JSONObject obj = (JSONObject) jsonArray.get(i);
FragmentClass fragment = new FragmentClass();
ft.add(R.id.pager, fragment);
args.putString("id", obj.get("id").toString());
fragment.setArguments(args);
}
ft.commit();
} catch (JSONException e) {
e.printStackTrace();
}
}
@Override
public Fragment getItem(int position) {
return new FragmentClass();
}
@Override
public int getCount() {
return NUM_PAGES;
}
}
}
最后,我的包含模拟对象的 MainActivity 是:
public class MainActivity extends AppCompatActivity {
private Button button;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button = findViewById(R.id.btn);
}
public void handleClick(View view){
String mockData = "{'data':[{'id':1},{'id':2}]}";
Intent intent = new Intent(MainActivity.this, ScreenSliderPagerActivity.class);
intent.putExtra("data",mockData);
MainActivity.this.startActivity(intent);
}
}
FragmentStatePagerAdapter
s 不是那样工作的。您不能将适配器的构造函数中的片段添加到片段管理器并期望它被添加到正确的位置。您必须 return 构造 片段 ,在 getItem(int)
方法中使用参数 :
private class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter {
public int NUM_PAGES; //making this a public variable within the inner class allows me to dynamically change the number of fragments created. In this instance, 2 will be created, one for each element of the array.
private ArrayList<FragmentClass> mFragments = new ArrayList<>();
public ScreenSlidePagerAdapter(FragmentManager fm, String data) {
super(fm);
try {
JSONObject json = new JSONObject(data);
JSONArray jsonArray = json.getJSONArray("data");
NUM_PAGES = jsonArray.length();
Log.d("NUM_PAGES", String.valueOf(NUM_PAGES)); //2
for (int i = 0; i < NUM_PAGES; i++){
JSONObject obj = (JSONObject) jsonArray.get(i);
Bundle args = new Bundle();
FragmentClass fragment = new FragmentClass();
args.putString("id", obj.get("id").toString());
fragment.setArguments(args);
mFragments.add(fragment);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
@Override
public Fragment getItem(int position) {
return mFragments.get(position);
}
@Override
public int getCount() {
return NUM_PAGES;
}
}
我编写了从远程端点获取 JSON 对象的代码。对于这个问题,我传入了一个模拟对象,它是一个对象数组。 我的目标是解构对象并为数组的每个元素在 ViewPager 中创建一个片段。每个片段都应该显示它所代表的对象的 ID。 对象看起来像这样:
{'data':[{'id':1},{'id':2}]}
如果我取消注释 FragmentClass 中的代码,每个片段都会显示“test”。但是,如果我尝试根据通过参数传递的值设置文本,我 运行 会出现此错误:
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object android.os.Bundle.get(java.lang.String)' on a null object reference
FragmentClass 的代码是:
public class FragmentClass extends Fragment {
private TextView txtId;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = (ViewGroup) inflater.inflate(
R.layout.fragment_screen_slide, container, false);
txtId = (TextView) rootView.findViewById(R.id.txtId);
txtId.setText(getArguments().get("id").toString());
// txtId.setText("test");
return rootView;
}
}
ViewPager class、ScreenSliderPagerActivity 的代码是:
public class ScreenSliderPagerActivity extends FragmentActivity {
private ViewPager mPager;
private PagerAdapter pagerAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
Intent intent = getIntent();
String data = intent.getStringExtra("data");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_screen_slide);
// Instantiate a ViewPager and a PagerAdapter.
mPager = (ViewPager) findViewById(R.id.pager);
pagerAdapter = new ScreenSlidePagerAdapter(getSupportFragmentManager(), data);
mPager.setAdapter(pagerAdapter);
}
@Override
public void onBackPressed() {
if (mPager.getCurrentItem() == 0) {
// If the user is currently looking at the first step, allow the system to handle the
// Back button. This calls finish() on this activity and pops the back stack.
super.onBackPressed();
} else {
// Otherwise, select the previous step.
mPager.setCurrentItem(mPager.getCurrentItem() - 1);
}
}
private class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter {
public int NUM_PAGES; //making this a public variable within the inner class allows me to dynamically change the number of fragments created. In this instance, 2 will be created, one for each element of the array.
public ScreenSlidePagerAdapter(FragmentManager fm, String data) {
super(fm);
try {
JSONObject json = new JSONObject(data);
JSONArray jsonArray = json.getJSONArray("data");
NUM_PAGES = jsonArray.length();
Log.d("NUM_PAGES", String.valueOf(NUM_PAGES)); //2
FragmentTransaction ft = fm.beginTransaction();
Bundle args = new Bundle();
// I think the problem is something in the loop, but I cannot seem to figure another way to do this.
for (int i = 0; i < NUM_PAGES; i++){
JSONObject obj = (JSONObject) jsonArray.get(i);
FragmentClass fragment = new FragmentClass();
ft.add(R.id.pager, fragment);
args.putString("id", obj.get("id").toString());
fragment.setArguments(args);
}
ft.commit();
} catch (JSONException e) {
e.printStackTrace();
}
}
@Override
public Fragment getItem(int position) {
return new FragmentClass();
}
@Override
public int getCount() {
return NUM_PAGES;
}
}
}
最后,我的包含模拟对象的 MainActivity 是:
public class MainActivity extends AppCompatActivity {
private Button button;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button = findViewById(R.id.btn);
}
public void handleClick(View view){
String mockData = "{'data':[{'id':1},{'id':2}]}";
Intent intent = new Intent(MainActivity.this, ScreenSliderPagerActivity.class);
intent.putExtra("data",mockData);
MainActivity.this.startActivity(intent);
}
}
FragmentStatePagerAdapter
s 不是那样工作的。您不能将适配器的构造函数中的片段添加到片段管理器并期望它被添加到正确的位置。您必须 return 构造 片段 ,在 getItem(int)
方法中使用参数 :
private class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter {
public int NUM_PAGES; //making this a public variable within the inner class allows me to dynamically change the number of fragments created. In this instance, 2 will be created, one for each element of the array.
private ArrayList<FragmentClass> mFragments = new ArrayList<>();
public ScreenSlidePagerAdapter(FragmentManager fm, String data) {
super(fm);
try {
JSONObject json = new JSONObject(data);
JSONArray jsonArray = json.getJSONArray("data");
NUM_PAGES = jsonArray.length();
Log.d("NUM_PAGES", String.valueOf(NUM_PAGES)); //2
for (int i = 0; i < NUM_PAGES; i++){
JSONObject obj = (JSONObject) jsonArray.get(i);
Bundle args = new Bundle();
FragmentClass fragment = new FragmentClass();
args.putString("id", obj.get("id").toString());
fragment.setArguments(args);
mFragments.add(fragment);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
@Override
public Fragment getItem(int position) {
return mFragments.get(position);
}
@Override
public int getCount() {
return NUM_PAGES;
}
}