带有 Viewpager 的嵌套子片段
Nested Child Fragment with Viewpager
目前,我正在尝试使用片段创建嵌套视图寻呼机,如何访问顶级父函数来刷新视图?
假设我有:
public class ParentFragment extends Fragment {
...{
...
viewPagerAdapter = new ViewPagerParentAdapter(getChildFragmentManager(), listOfItem);
viewPager.setAdapter(viewPagerAdapter);
}
public void refreshView(){
loadData();
}
private class ViewPagerParentAdapter extends FragmentStatePagerAdapter{
private List<String> tabTitle;
private List<Item> listOfItem;
public ViewPagerParentAdapter(FragmentManager fm, @NonNull List<Item> listOfItem) {
super(fm);
this.tabTitle = new ArrayList<>();
this.listOfItem = new ArrayList<>();
if (listOfItem.size() > 0) {
this.listOfItem = listOfItem;
for (Item item : this.listOfItem) {
tabTitle.add(Item.getCLASSIFICATION());
}
}
notifyDataSetChanged();
}
@Override
public Fragment getItem(int position) {
return DetailFragment.newInstance(getItemAtPosition(position).getDETAILS());
}
public Item getItemAtPosition(int position) {
return listOfItem != null ? listOfItem.get(position) : null;
}
}
}
这是我的对象
public class Item{
//POJO
private String CLASSIFICATION;
private Details details;
}
详细片段
public class DetailFragment extends Fragment{
...{
...
Details details = getArguments().getParcelable("details");
viewPagerAdapter = new DetailViewPagerAdapter(getChildFragmentManager(), details);
viewPagerDetails.setAdapter(viewPagerAdapter);
}
public void refreshParentView(){
((ParentFragment) getParentFragment()).refreshView(); //getting Null
}
public class DetailViewPagerAdapter extends FragmentStatePagerAdapter {
String[] tabTitle = {"Components", "Materials", "Descriptions"};
Details details;
public DetailViewPagerAdapter(FragmentManager fm, @NonNull Details details) {
super(fm);
this.details = details;
notifyDataSetChanged();
}
@Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return DetailsChildFragment.newInstance(details.getCOMPONENT());
case 1:
return DetailsChildFragment.newInstance(details.getMATERIAL());
case 2:
return DetailsChildFragment.newInstance(details.getDESC());
}
return null;
}
@Override
public int getCount() {
return tabTitle.length;
}
}
}
最后一个子片段
public class DetailsChildFragment extends Fragment implements View.OnClickListener{
...{
...
...
Button buttonRefresh = (Button)getView().findViewById(R.id.button_refresh);
buttonRefresh.setOnClickListener(this);
}
@Override
public void onClick(View view){
switch(view.getId()){
case R.id.button_refresh:
((DetailFragment)getParentFragment()).refreshParentView();
break;
}
}
}
目前我在细节片段上得到 Null refreshParentView
有什么建议吗?提前致谢
当您添加 DetailFragment 时使用标签进行操作,以便您可以在需要时检索它的实例。示例:
getSupportFragmentManager().beginTransaction().add(R.id.fragment_container, detailFragment,"detailFragmentTag").commit();
现在,任何时候你需要访问这个片段,你只需要调用
DetailFragment parentFragment = (DetailFragment) getActivity().getSupportFragmentManager().findFragmentByTag("detailFragmentTag");
if(detailFragment != null && detailFragment.isAdded()){ //check if it is not null and it is added to the view so you dont end up in some NPE
detailFragment.refreshParentView()
对于 child
中发生的事件,您可以将 interface
用作 Listener
public interface Listener{
void onRefreshButtonClicked();
}
child 片段需要有一个 Listener
作为字段,然后你可以在获取 child 片段的实例时设置 Listener
。
public class ChildFragment extends Fragment{
private Listener listener;
public void setListener(Listener listener)//setter
...
//now on button click you call the listener
refreshButton.setOnClickListener(new View.OnClickListener(){
@Override onClick(){
if(listener!=null){
listener.onRefreshButtonClicked();
}
}
}
public class ParentFragment extends Fragment{
...
ChildFragment child = ChildFragment.getInstance()
child.setListener(new Listener(){
@Override
void onRefreshButtonClicked(){
// implement your logic
}
}
这样做的一个好处是您不需要将 parent 从 Fragment
转换为 ParentFragment
,这样您的代码就会 re-usable永远需要
目前,我正在尝试使用片段创建嵌套视图寻呼机,如何访问顶级父函数来刷新视图?
假设我有:
public class ParentFragment extends Fragment {
...{
...
viewPagerAdapter = new ViewPagerParentAdapter(getChildFragmentManager(), listOfItem);
viewPager.setAdapter(viewPagerAdapter);
}
public void refreshView(){
loadData();
}
private class ViewPagerParentAdapter extends FragmentStatePagerAdapter{
private List<String> tabTitle;
private List<Item> listOfItem;
public ViewPagerParentAdapter(FragmentManager fm, @NonNull List<Item> listOfItem) {
super(fm);
this.tabTitle = new ArrayList<>();
this.listOfItem = new ArrayList<>();
if (listOfItem.size() > 0) {
this.listOfItem = listOfItem;
for (Item item : this.listOfItem) {
tabTitle.add(Item.getCLASSIFICATION());
}
}
notifyDataSetChanged();
}
@Override
public Fragment getItem(int position) {
return DetailFragment.newInstance(getItemAtPosition(position).getDETAILS());
}
public Item getItemAtPosition(int position) {
return listOfItem != null ? listOfItem.get(position) : null;
}
}
}
这是我的对象
public class Item{
//POJO
private String CLASSIFICATION;
private Details details;
}
详细片段
public class DetailFragment extends Fragment{
...{
...
Details details = getArguments().getParcelable("details");
viewPagerAdapter = new DetailViewPagerAdapter(getChildFragmentManager(), details);
viewPagerDetails.setAdapter(viewPagerAdapter);
}
public void refreshParentView(){
((ParentFragment) getParentFragment()).refreshView(); //getting Null
}
public class DetailViewPagerAdapter extends FragmentStatePagerAdapter {
String[] tabTitle = {"Components", "Materials", "Descriptions"};
Details details;
public DetailViewPagerAdapter(FragmentManager fm, @NonNull Details details) {
super(fm);
this.details = details;
notifyDataSetChanged();
}
@Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return DetailsChildFragment.newInstance(details.getCOMPONENT());
case 1:
return DetailsChildFragment.newInstance(details.getMATERIAL());
case 2:
return DetailsChildFragment.newInstance(details.getDESC());
}
return null;
}
@Override
public int getCount() {
return tabTitle.length;
}
}
}
最后一个子片段
public class DetailsChildFragment extends Fragment implements View.OnClickListener{
...{
...
...
Button buttonRefresh = (Button)getView().findViewById(R.id.button_refresh);
buttonRefresh.setOnClickListener(this);
}
@Override
public void onClick(View view){
switch(view.getId()){
case R.id.button_refresh:
((DetailFragment)getParentFragment()).refreshParentView();
break;
}
}
}
目前我在细节片段上得到 Null refreshParentView
有什么建议吗?提前致谢
当您添加 DetailFragment 时使用标签进行操作,以便您可以在需要时检索它的实例。示例:
getSupportFragmentManager().beginTransaction().add(R.id.fragment_container, detailFragment,"detailFragmentTag").commit();
现在,任何时候你需要访问这个片段,你只需要调用
DetailFragment parentFragment = (DetailFragment) getActivity().getSupportFragmentManager().findFragmentByTag("detailFragmentTag");
if(detailFragment != null && detailFragment.isAdded()){ //check if it is not null and it is added to the view so you dont end up in some NPE
detailFragment.refreshParentView()
对于 child
中发生的事件,您可以将interface
用作 Listener
public interface Listener{
void onRefreshButtonClicked();
}
child 片段需要有一个 Listener
作为字段,然后你可以在获取 child 片段的实例时设置 Listener
。
public class ChildFragment extends Fragment{
private Listener listener;
public void setListener(Listener listener)//setter
...
//now on button click you call the listener
refreshButton.setOnClickListener(new View.OnClickListener(){
@Override onClick(){
if(listener!=null){
listener.onRefreshButtonClicked();
}
}
}
public class ParentFragment extends Fragment{
...
ChildFragment child = ChildFragment.getInstance()
child.setListener(new Listener(){
@Override
void onRefreshButtonClicked(){
// implement your logic
}
}
这样做的一个好处是您不需要将 parent 从 Fragment
转换为 ParentFragment
,这样您的代码就会 re-usable永远需要