编辑:
从更多的问题来看,我几乎肯定的是问题在于,当我在FragmentActivity
的onCreate()方法中夸大布局时,ViewPager中有不同的视图。因此,当我尝试使用xml1.findViewById()
访问它们时,它会查看不同的视图。如何访问ViewPager
中使用的视图?查看我的FragmentPagerAdapter
,看起来片段每次超过1次滑动时都会被创建为新对象。我想要将所有4个视图初始化一次。然后,每当我调用updateUI
时,四个视图会立即被更改。所以我可以在他们新近更新的所有四个视图之间滑动。
我尝试使用pagerAdapter.getItem(index).getView().findViewById( )
,但它返回NullPointerException
。我收到异常后,尝试覆盖getView()
类中的Fragment
方法。我在方法中添加的只是return view;
,其中view是onCreateView
方法中返回的View的保存实例。这导致我的ViewPager显示4个空白屏幕以进行滑动。
我将FragmentPagerAdapter
实施添加到问题的底部。
结束修改
我尝试使用Fragments
来实施ViewPager
。我的结果非常奇怪。
private TextView view1a, view1b;
private TextView view2a, view2b;
private TextView view3a, view3b;
private TextView view4a, view4b;
private Spinner spinner1, spinner2, spinner3, spinner4;
private Checkbox check1, check2, check3, check4;
private ViewPager mViewPager;
private View xml1, xml2, xml3, xml4;
public void onCreate( Bundle savedInstanceState ) {
super.onCreate( savedInstanceState );
setContentView( R.layout.main_page );
mViewPager = (ViewPager) findViewById( R.id.pager );
FragmentManager fm = getSupportFragmentManager();
MoreParmsFragmentPagerAdapter pagerAdapter = new MoreParmsFragmentPagerAdapter(fm);
xml1 = LayoutInflater.from( getBaseContext()).inflate( R.layout.xml1, null );
xml2 = LayoutInflater.from( getBaseContext()).inflate( R.layout.xml2, null );
xml3 = LayoutInflater.from( getBaseContext()).inflate( R.layout.xml3, null );
xml4 = LayoutInflater.from( getBaseContext()).inflate( R.layout.xml4, null );
populateSpinners();
updateUI();
}
public void populateSpinners() {
array1Adapter = new ArrayAdapter<String>( this, android.R.layout.simple_spinner_item, res.getStringArray( R.array.array1 ) );
array1Adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner1 = (Spinner) xml1.findViewById(R.id.spinner1);
spinner1.setAdapter(array1Adapter);
array2Adapter = new ArrayAdapter<String>( this, android.R.layout.simple_spinner_item, res.getStringArray( R.array.array2 ) );
array2Adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner2 = (Spinner) xml2.findViewById(R.id.spinner2);
spinner2.setAdapter(array2Adapter);
array3Adapter = new ArrayAdapter<String>( this, android.R.layout.simple_spinner_item, res.getStringArray( R.array.array3 ) );
array3Adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner3 = (Spinner) xml3.findViewById(R.id.spinner3);
spinner3.setAdapter(array3Adapter);
array4Adapter = new ArrayAdapter<String>( this, android.R.layout.simple_spinner_item, res.getStringArray( R.array.array4 ) );
array4Adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner4 = (Spinner) xml4.findViewById(R.id.spinner4);
spinner4.setAdapter(array4Adapter);
}
public void updateUI() {
view1a = (TextView) xml1.findViewById( R.id.view_one_a );
view1b = (TextView) xml1.findViewById( R.id.view_one_b );
view2a = (TextView) xml2.findViewById( R.id.view_two_a );
view2b = (TextView) xml2.findViewById( R.id.view_two_b );
view3a = (TextView) xml3.findViewById( R.id.view_three_a );
view3b = (TextView) xml3.findViewById( R.id.view_three_b );
view4a = (TextView) xml4.findViewById( R.id.view_four_a );
view4b = (TextView) xml4.findViewById( R.id.view_four_b );
// There is work done here to determine what to set
// the different TextViews' text to.
//
// `view**.setText()` is called for all views above with their respective values.
spinner1 = (Spinner) xml1.findViewById( R.id.spinner1 );
spinner2 = (Spinner) xml2.findViewById( R.id.spinner2 );
spinner3 = (Spinner) xml3.findViewById( R.id.spinner3 );
spinner4 = (Spinner) xml4.findViewById( R.id.spinner4 );
// There is work done here to determine what index the Spinners
// should have selected.
//
// `Spinner.setSelection( index ) is called on all spinners.
check1 = (CheckBox) xml1.findViewById( R.id.check1 );
check2 = (CheckBox) xml2.findViewById( R.id.check2 );
check3 = (CheckBox) xml3.findViewById( R.id.check3 );
check4 = (CheckBox) xml4.findViewById( R.id.check4 );
// There is work done here to determine whether or not
// to check the CheckBoxes.
//
// CheckBox.setChecked() is called for all checkboxes.
}
}
这是我的Fragment
课程的一个例子:
public class xmlOneFragment extends Fragment {
int mCurrentPage;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
/** Getting the arguments to the Bundle object */
Bundle data = getArguments();
/** Getting integer data of the key current_page from the bundle */
mCurrentPage = data.getInt("current_page", 0);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.xml1, container,false);
return v;
}
}
FIRST 问题是Spinners
永远不会填充相应的数组。我的LogCat
方法中有populateSpinners()
次调用,告诉我我的期望,但Spinners
本身并未填充。
SECOND 问题出现在updateUI()
方法中。所有findViewById()
次调用下面的评论都是我进行某些计算以确定要放入TextViews
的文本,设置Spinners
的索引以及是否检查CheckBoxes
。我有LogCat
次调用显示找到的值,它们都是预期的。
调用.setText(), .setSelection(), and .setChecked()
方法时,不会显示任何错误,但根本没有设置任何项目。一切都是空白的。
THIRD 问题让我感到困惑。 TextViews
现在都有唯一的ID。当我第一次尝试实现此ViewPager
时,我使用updateUI()
方法处理TextViews而xml*.
调用没有findViewById()
前缀。
view1a = (TextView) findViewById( R.id.view_one_a );
view1b = (TextView) findViewById( R.id.view_one_b );
view2a = (TextView) findViewById( R.id.view_two_a );
view2b = (TextView) findViewById( R.id.view_two_b );
view3a = (TextView) findViewById( R.id.view_three_a );
view3b = (TextView) findViewById( R.id.view_three_b );
view4a = (TextView) findViewById( R.id.view_four_a );
view4b = (TextView) findViewById( R.id.view_four_b );
// There is work done here to determine what to set
// the different TextViews' text to.
view**.setText( whatever );
此方法产生NullPointerException
,但仅在第三页和第四页上使用.setText()
调用TextViews
时。前两页没有任何例外。所以我评论了第三和第四页。程序运行,前两页在正确的TextViews中显示正确的值。然后我尝试将xml*.
添加到findViewById()
方法,现在没有抛出异常,但根本没有更新视图。
最后注意事项 ViewPager
功能正常,我可以非常好地在适当的布局之间滑动。当我尝试使用我想要的值更新视图时出现问题。我假设问题与我如何夸大布局有关,或者我如何做太多次。第三个问题让我很困惑。我找不到第一页/第二页和第三页/第四页之间的任何差异,但它们显然表现不同。另外,显示的第一个代码块表示为Activity
,第二个代码块表示为FragmentActivity
。
编辑以添加FragmentPagerAdapter
public class MoreParmsFragmentPagerAdapter extends FragmentPagerAdapter {
final int PAGE_COUNT = 4;
public MoreParmsFragmentPagerAdapter( FragmentManager fm ) {
super(fm);
}
public Fragment getItem( int arg0 ) {
if( arg0 == 0 ) {
xmlOneFragment xml1Frag = new xmlOneFragment();
Bundle data = new Bundle();
data.putInt( "current_page", arg0 );
xmlOneFrag.setArguments( data );
return xmlOneFrag;
} else if( arg0 == 1 ) {
xmlTwoFragment xml2Frag = new xmlTwoFragment();
Bundle data = new Bundle();
data.putInt( "current_page", arg0 );
xmlTwoFrag.setArguments( data );
return xmlTwoFrag;
} else if( arg0 == 2 ) {
xmlThreeFragment xml3Frag = new xmlThreeFragment();
Bundle data = new Bundle();
data.putInt( "current_page", arg0 );
xmlThreeFrag.setArguments( data );
return xmlThreeFrag;
} else {
xmlFourFragment xml4Frag = new xmlFourFragment();
Bundle data = new Bundle();
data.putInt( "current_page", arg0 );
xmlFourFrag.setArguments( data );
return xmlFourFrag;
}
}
@Override
public CharSequence getPageTitle(int position) {
if( position == 0 ) {
return "xml1";
} else if( position == 1 ){
return "xml2";
} else if( position == 2 ) {
return "xml3";
} else {
return "xml4";
}
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return PAGE_COUNT;
}
}
编辑2:
private ViewPager mViewPager;
private MoreParmsFragmentPagerAdapter pagerAdapter;
private FragmentManager fm;
private AntiPumpFragment apFrag;
private RelaxedCloseFragment relFrag;
private MiscParmsFragment miscFrag;
private DNP3Fragment dnpFrag;
public void onCreate( Bundle savedInstanceState ) {
super.onCreate( savedInstanceState );
mViewPager = (ViewPager) findViewById( R.id.pager );
fm = getSupportFragmentManager();
pagerAdapter = new MoreParmsFragmentPagerAdapter(fm);
mViewPager.setAdapter( pagerAdapter );
apFrag = (AntiPumpFragment) fm.findFragmentByTag( "android:switcher:" + R.id.pager + ":0" );
relFrag = (RelaxedCloseFragment) fm.findFragmentByTag( "android:switcher:" + R.id.pager + ":1" );
miscFrag = (MiscParmsFragment) fm.findFragmentByTag( "android:switcher:" + R.id.pager + ":2" );
dnpFrag = (DNP3Fragment) fm.findFragmentByTag( "android:switcher:" + R.id.pager + ":3" );
在我的代码中,所有这些片段都返回null。 ViewPager
在我的屏幕上正确显示,我可以干净地在所有四个视图之间滑动。但是,我的所有if( apFrag != null )
语句都会被跳过。
答案 0 :(得分:1)
第一个问题是Spinners永远不会充满他们的 相应的数组。我的整个过程都有LogCat调用 populateSpinners()方法向我展示了我的期望,但是Spinners 他们自己没有人口。
正如您稍后发现的那样,您没有看到Spinners
已初始化,因为您只是使用了Fragments
来自ViewPager
LayoutInflater
的视图,而不是Fragments
从Activity
中使用的布局文件中展开新视图。初始化此新视图的子视图不会显示任何视觉效果,因为它不存在/显示在ViewGroup
的用户界面中,它会“浮动”,等待您将其附加到Activity
中View
所以它可以显示它有哪些观点。
在updateUI()方法中出现了SECOND问题。以下评论 所有findViewById()调用都是我进行某些计算的地方 确定要在TextViews中放入什么文本,设置什么索引 旋转器,以及是否检查CheckBoxes。我有LogCat 显示找到的值的调用,它们都是预期的。 当.setText(),. setSelection()和.setChecked()方法是 调用时,不显示任何错误,但根本没有设置任何项目。 一切都空白。
与一个点相同,您没有初始化显示的视图,您正在更新未附加的ViewPager
层次结构。
第三个问题让我感到困惑。现在是TextViews 都有唯一的ID。当我第一次尝试实现这个ViewPager时,我 如果没有xml *,updateUI()方法处理TextViews。字首 到findViewById()调用。[...]这个方法产生了一个 NullPointerException,但仅在使用.setText()调用时 第三页和第四页上的TextViews。前两页没有 扔任何例外
也许这会让事情变得清晰:ListView
除了允许左右滑动之外,还设计(通过适配器)以允许尽可能少地使用视图(例如ViewPager
,它仅为可见行膨胀行。为此,它只构建一定数量的页面。默认情况下,此页数为3(一页可见+每侧一页,因此滑动将是平滑的),ViewPager
将在您向前或向后滑动时开始加载其他页面。当您启动NullPointerException
时,它将加载第一页(可见的)或下一页(右侧),以便用户可以立即滑动。其他两个页面未加载以提高效率,并且尝试从它们访问窗口小部件将抛出ViewPager
,因为它们无法找到。而且,如果用户可能根本看不到这些页面,那么最终你不应该做不必要的工作。现在,您可以修改setOffscreenPageLimit()
创建并保留在内存中的页数(使用geItem()
并提供一个数字)但是您应该尽量避免它的效率,因为这会加载所有内存中的小部件一下子(在你的情况下,这可能不会那么糟糕,但我不知道你想做什么)。
我尝试使用pagerAdapter.getItem(index).getView()。findViewById(), 但它返回NullPointerException。我得到例外后,我 尝试重写我的Fragment类中的getView()方法。我 放入方法是返回视图;,其中视图是保存的实例 onCreateView方法返回的视图。这导致了我的 ViewPager显示4个空白屏幕之间的滑动。
您无法使用适配器的Fragment
方法,因为这不会返回ViewPager
当前使用的Fragment
实例,它会返回 new Activity
刚刚实例化。由于它刚刚实例化而未附加到getView()
,因此其ViewPager
方法不会返回视图。
如何访问ViewPager中使用的视图?
这取决于您何时想要访问它们。如果您在Fragments
上设置适配器时数据可用,则只需在onCreateView
或onActivityCreated
方法的Fragment
中移动初始化。
如果您想稍后访问ViewPager
中的ViewPager
,您可以使用小型黑客,知道Fragments
添加(暂时)FragmentManager
在android:switcher:theIdOfTheViewPager:thePositionInTheViewPager
中使用Fragment
形式的特殊标记。例如,要访问ViewPager
的第一个xmlOneFragment first = (xmlOneFragment)getSupportFragmentManager().findFragmentByTag("android:switcher:" + R.id.pager + ":0");
// if the fragment is found and its view is available do stuff
if (first != null && first.getView() != null) {
// do stuff
}
:
ViewPager
不是最佳解决方案,但它会对您有用,直到您对{{1}}更加了解。