![](/img/trans.png)
[英]getSupportFragmentManager().findFragmentById returns null with FragmentPagerAdapter and ViewPager
[英]findFragmentById returns null after implementing ViewPager
我按照本教程来实现 ViewPager(不创建 tablayout): https ://www.javacodegeeks.com/2013/04/android-tutorial-using-the-viewpager.html
它有效,但我遇到了麻烦:
当我尝试执行findFragmentById(R.id.my_fragment)
,它返回空值。 我认为这是因为在我的activity_main.xml
中只有 ViewPager
我试图在我的activity_main.xml
添加一个<fragment>
,现在我可以使用findFragmentById(R.id.my_fragment)
访问我的片段,但我的 ViewPager 现在无法工作
有没有办法访问我的 Fragment ? 我需要访问他的观点。
这是我的 activity_main.xml :
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<androidx.viewpager.widget.ViewPager
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>`enter code here`
这是我的 MainActivity 的 onCreate
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView((int) R.layout.activity_main);
scan_fragment = (ScanFragment) getSupportFragmentManager().findFragmentById(R.id.scan_fragment);
nfcButton = (ImageButton) findViewById(R.id.nfc_button);
integrator = new IntentIntegrator(this);
pendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
//
anim = ObjectAnimator.ofFloat(this.nfcButton, "scaleX", new float[]{0.9f});
anim2 = ObjectAnimator.ofFloat(this.nfcButton, "scaleY", new float[]{0.9f});
List<Fragment> fragments = getFragments();
pageAdapter = new MyPageAdapter(getSupportFragmentManager(), fragments);
ViewPager pager = (ViewPager) findViewById(R.id.viewpager);
pager.setAdapter(pageAdapter);
}
private List<Fragment> getFragments() {
List<Fragment> fList = new ArrayList<Fragment>();
fList.add(ScanFragment.newInstance("Fragment 1"));
fList.add(WebFragment.newInstance("Fragment 2"));
return fList;
}
我的页面适配器
class MyPageAdapter extends FragmentPagerAdapter {
private List<Fragment> fragments;
public MyPageAdapter(FragmentManager fm, List<Fragment> fragments) {
super(fm);
this.fragments = fragments;
}
@Override
public Fragment getItem(int position) {
return this.fragments.get(position);
}
@Override
public int getCount() {
return this.fragments.size();
}
}
我的 Fragment 的重要部分:
public interface OnButtonClickedListener {
public void onButtonClicked(View view);
}
public static final ScanFragment newInstance(String message)
{
ScanFragment f = new ScanFragment();
Bundle bdl = new Bundle(1);
bdl.putString(EXTRA_MESSAGE, message);
f.setArguments(bdl);
return f;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_scan, container, false);
mainActivity = (MainActivity) getActivity();
MainActivity.display = 0;
qrButton = (ImageButton) view.findViewById(R.id.main_button);
nfcButton = (ImageButton) view.findViewById(R.id.nfc_button);
anim = ObjectAnimator.ofFloat(this.nfcButton, "scaleX", new float[]{0.9f});
anim2 = ObjectAnimator.ofFloat(this.nfcButton, "scaleY", new float[]{0.9f});
nfcButton.setOnClickListener(this);
qrButton.setOnClickListener(this);
return view;
}
我的片段的 XML 只包含几个按钮和图像
很抱歉让您失望了,但是您正在关注的教程已损坏,您不应该关注它。
参见https://proandroiddev.com/the-seven-actually-10-cardinal-sins-of-android-development-491d2f64c8e0 中的#3,
按照这个要点https://gist.github.com/Zhuinden/c643f03a023a9cbe83fff6c75c948d3b#file-myfragmentpageradapter-kt
.
class MyFragmentPagerAdapter(
private val context: Context,
fragmentManager: FragmentManager
) : FragmentPagerAdapter(fragmentManager) {
override fun getCount() = 2
override fun getItem(position: Int) = when(position) {
0 -> FirstFragment()
1 -> SecondFragment()
else -> throw IllegalStateException("Unexpected position $position")
}
override fun getPageTitle(position: Int): CharSequence = when(position) {
0 -> context.getString(R.string.first)
1 -> context.getString(R.string.second)
else -> throw IllegalStateException("Unexpected position $position")
}
}
class ParentFragment: Fragment() {
override fun onCreateView(...) = ...
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewPager.adapter = MyFragmentPagerAdapter(requireContext(), childFragmentManager)
tabLayout.setupWithViewPager(viewPager)
}
}
和
Fragment fragment = childFragmentManager.findFragmentByTag("android:switcher:" + viewPager.getId() + ":" + fragmentPosition);
可能是因为 ViewPager 没有让所有的片段都保持活动状态,只有当前的一个和另外 2 个在 onPause() 中位于其一侧,所以会出现错误。 其他人没有为 Activity 创建的视图,但我们可以通过 ViewPager 访问它们,因为 Fragment 的实例已经保存。
我希望以下代码可以帮助您:
/******************************************/
//Your ADAPTER.
class MyPageAdapter extends FragmentPagerAdapter {
private List<Fragment> fragments;
//Your code...
/**
* Use this method for get the fragments list.
*/
public List<Fragment> getFragments(){
return fragments;
}
}
/******************************************/
//In your ACTIVITY.
private List<Fragment> getFragments() {
pageAdapter.getFragments();
}
/**
* Use this to find a view and cast for your needs.
*/
private View findById(int fragmentIndex, int viewId){
Fragment fragment = this.getFragments().get(fragmentIndex);
View view = ((YourFragment) fragment).getView(); //Casting to YourFragment and catching root view.
return view.findViewById(viewId);
}
/******************************************/
//In your FRAGMENTS.
//Must save fragment rootView to access to findById() method. For example:
public class YourFragment extends Fragment{
private View view;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_scan, container, false);
//Your code....
return view;
}
public View getView(){
return view;
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.