我正在使用兼容性库中的ViewPager.我已经巧妙地让它显示了几个我可以翻阅的视图.
但是,我很难弄清楚如何使用一组新视图更新ViewPager.
我已经试过各种事情就像调用mAdapter.notifyDataSetChanged(),mViewPager.invalidate()即使每次都创建我想用一个新的数据列表中的一个全新的适配器.
没有任何帮助,文本视图与原始数据保持不变.
更新: 我做了一个小测试项目,我几乎能够更新视图.我将粘贴下面的课程.
然而,似乎没有更新的是第二个视图,"B"仍然存在,按下更新按钮后应显示"Y".
public class ViewPagerBugActivity extends Activity {
private ViewPager myViewPager;
private List<String> data;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
data = new ArrayList<String>();
data.add("A");
data.add("B");
data.add("C");
myViewPager = (ViewPager) findViewById(R.id.my_view_pager);
myViewPager.setAdapter(new MyViewPagerAdapter(this, data));
Button updateButton = (Button) findViewById(R.id.update_button);
updateButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
updateViewPager();
}
});
}
private void updateViewPager() {
data.clear();
data.add("X");
data.add("Y");
data.add("Z");
myViewPager.getAdapter().notifyDataSetChanged();
}
private class MyViewPagerAdapter extends PagerAdapter {
private …Run Code Online (Sandbox Code Playgroud) 我无法更新ViewPager中的内容.
一个问题:FragmentPagerAdapter类中的方法instantiateItem()和getItem()的关系和正确用法是什么?
我只使用getItem()实例化并返回我的片段:
@Override
public Fragment getItem(int position) {
return new MyFragment(context, paramters);
}
Run Code Online (Sandbox Code Playgroud)
这很好用(但据说我不能改变内容).
所以我发现了这个:ViewPager PagerAdapter没有更新View
特别是在其中讨论了方法instantiateItem():
"我的方法是对instantiateItem()方法中的任何实例化视图使用setTag()方法"
所以现在我想实现instantiateItem()才能做到这一点.但我不知道我必须返回那里(return是Object)和getItem(int position)的关系是什么?
目前我正在使用getItem来实例化Fragment,这是错的吗?但是,我是否必须将片段放在实例变量中,或者根本不实现getItem()......?我只是不明白.
我试过阅读参考资料:
public abstract Fragment getItem(int position)
返回与指定位置关联的片段.
public Object instantiateItem(ViewGroup容器,int位置)
创建给定位置的页面.适配器负责将视图添加到此处给出的容器,但它必须确保在从finishUpdate(ViewGroup)返回时完成此操作.参数
容器包含将在其中显示页面的View.position要实例化的页面位置.
返回
返回表示新页面的Object.这不需要是View,但可以是页面的其他容器.
......但我仍然不明白它们是如何相关的以及我必须做些什么.
这是我的代码.我正在使用支持包v4.
ViewPagerTest
public class ViewPagerTest extends FragmentActivity {
private ViewPager pager;
private MyFragmentAdapter adapter;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.pager1);
pager = (ViewPager)findViewById(R.id.slider);
String[] data = {"page1", "page2", "page3", "page4", "page5", "page6"};
adapter = new MyFragmentAdapter(getSupportFragmentManager(), 6, this, …Run Code Online (Sandbox Code Playgroud) 我正在尝试从ViewPager动态添加和删除片段,添加工作没有任何问题,但删除不能按预期工作.
每次我想删除当前项目时,最后一项将被删除.
我还尝试使用FragmentStatePagerAdapter或在适配器的getItemPosition方法中返回POSITION_NONE.
我究竟做错了什么?
这是一个基本的例子:
MainActivity.java
public class MainActivity extends FragmentActivity implements TextProvider {
private Button mAdd;
private Button mRemove;
private ViewPager mPager;
private MyPagerAdapter mAdapter;
private ArrayList<String> mEntries = new ArrayList<String>();
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mEntries.add("pos 1");
mEntries.add("pos 2");
mEntries.add("pos 3");
mEntries.add("pos 4");
mEntries.add("pos 5");
mAdd = (Button) findViewById(R.id.add);
mRemove = (Button) findViewById(R.id.remove);
mPager = (ViewPager) findViewById(R.id.pager);
mAdd.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
addNewItem();
}
});
mRemove.setOnClickListener(new OnClickListener() {
@Override
public void …Run Code Online (Sandbox Code Playgroud) 有一个用例,ViewPager我从来没有见过相当实现.
ViewPager或多或少的静态结构.将页面添加到右侧(附加到模型并显示它)并不困难,但是,应该有一个很好用的解决方案来扩展PagerAdapter(或其某些子类),以便它可以在两个方向上扩展.
我可以想象这样的适配器接口
boolean isEmpty()
boolean hasNext()
boolean hasPrevious()
Object getNext()
Object getPrevious()
Object getItem(int position)
// or if using generics
T getNext()
T getPrevious()
T getItem(int position)
Run Code Online (Sandbox Code Playgroud)
与Collections Iterator类似,但都是双向的.
索引/位置不限于0以下,但可以使用整个范围的整数类型.
也许不是基于数组的实现(从0到无限).
我发现这个"hack":动态添加和删除view到viewpager
但是正如我之前所说,我试图让它自然地工作,而不是维护3,5,...项目并强制ViewPager更改当前位置在一些扭曲的逻辑上
目前是否有足够的实施或是否有必要实施它?
如果这将是一个全新的实施,我愿意赏金奖励回答.
我正在使用viewpager和片段制作一个adroid应用程序.我想选择动态地向分页器添加或删除片段页面.我有一个自定义FragmentPagerAdapter:
public class MyAdapter extends FragmentPagerAdapter implements TitleProvider{
protected final List<PageFragment> fragments;
/**
* @param fm
* @param fragments
*/
public MyAdapter(FragmentManager fm, List<PageFragment> fragments) {
super(fm);
this.fragments = fragments;
}
public void addItem(PageFragment f){
fragments.add(f);
notifyDataSetChanged();
}
public void addItem(int pos, PageFragment f){
for(int i=0;i<fragments.size();i++){
if(i>=pos){
getSupportFragmentManager().beginTransaction().remove(getSupportFragmentManager().findFragmentByTag(getFragmentTag(i))).commit();
}
}
fragments.add(pos,f);
notifyDataSetChanged();
pager.setAdapter(this);
pager.setCurrentItem(pos);
}
public void removeItem(int pos){
getSupportFragmentManager().beginTransaction().remove(getSupportFragmentManager().findFragmentByTag(getFragmentTag(pos))).commit();
for(int i=0;i<fragments.size();i++){
if(i>pos){
getSupportFragmentManager().beginTransaction().remove(getSupportFragmentManager().findFragmentByTag(getFragmentTag(i))).commit();
}
}
fragments.remove(pos);
notifyDataSetChanged();
pager.setAdapter(this);
if(pos<fragments.size()){
pager.setCurrentItem(pos);
}else{
pager.setCurrentItem(pos-1);
}
}
@Override
public Fragment getItem(int position) …Run Code Online (Sandbox Code Playgroud) UPDATE
经过一番与这个问题的重大斗争和SO用户的帮助后,我设法解决了这个问题.这就是我clearProgressUpTo现在的样子.
public void clearProgressUpTo(int progress) {
boolean deleted = false;
for (int i = fragments.size() - 1; i > 0; i--) {
int key = fragments.keyAt(i);
if (key != progress) {
fragments.delete(key);
deleted = true;
} else {
break;
}
}
if (deleted)
notifyDataSetChanged(); //prevents recursive call (and IllegalStateException: Recursive entry to executePendingTransactions)
while (mSavedState.size() > progress) {
mSavedState.remove(mSavedState.size()-1);
}
}
Run Code Online (Sandbox Code Playgroud)
我之所以这样做notifyDataSetChanged是因为initiateItem我mSavedState再次填满了我.而且我确信在通知我之后我adapter不会持有任何这些Fragments.
此外,如果你想这样做改变你的mSaveState,protected所以你将能够从扩展类(在我的情况下 …
我在viewpager实现中膨胀视图(而不是片段).我的主要课程扩展了Activity.当我尝试从我的应用程序或从中滑动屏幕时,我遇到此错误
at com.example.app.CustomPagerAdapter.instantiateItem(CustomPagerAdapter.java:47)
和
01-04 16:44:35.5278614-8614/com.parsizabanan.app W/dalvikvm? threadid=1: thread exiting with uncaught exception (group=0x4195ee48)
01-04 16:44:35.5278614-8614/com.parsizabanan.app E/AndroidRuntime? FatAL EXCEPTION: main
Process: com.parsizabanan.app, PID: 8614
android.view.InflateException: Binary XML file line #6: Error inflating class <unknown>
at android.view.LayoutInflater.createView(LayoutInflater.java:620)
at com.android.internal.policy.impl.PhoneLayoutInflater.onCreateView(PhoneLayoutInfl ater.java:56)
at android.view.LayoutInflater.onCreateView(LayoutInflater.java:669)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:694)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:755)
at android.view.LayoutInflater.inflate(LayoutInflater.java:492)
at android.view.LayoutInflater.inflate(LayoutInflater.java:397)
at android.view.LayoutInflater.inflate(LayoutInflater.java:353)
at com.parsizabanan.app.CustomPagerAdapter.instantiateItem(CustomPagerAdapter.java:47)
at android.support.v4.view.PagerAdapter.instantiateItem(PagerAdapter.java:110)
at android.support.v4.view.ViewPager.addNewItem(ViewPager.java:837)
at android.support.v4.view.ViewPager.populate(ViewPager.java:1021)
at android.support.v4.view.ViewPager.populate(ViewPager.java:919)
at android.support.v4.view.ViewPager.onMeasure(ViewPager.java:1441)
at android.view.View.measure(View.java:16574)
at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:719)
at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:455)
at android.view.View.measure(View.java:16574)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5140)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
at android.view.View.measure(View.java:16574)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5140)
at …Run Code Online (Sandbox Code Playgroud) 我在恢复View内部状态方面遇到了麻烦ViewPager.该内容ViewPager是一个视图扩展FrameLayout.
问题是FrameLayout.onRestoreInstanceState()如果以编程方式添加到中,则不会被调用ViewPager
这是我的代码 Activity.java
private ViewPager vPager;
private MainPagerAdapter mAdapter;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
setContentView(R.layout.activity_layout);
// all the findViewById stuff
CustomView cv1 = new CustomView(this);
CustomView cv2 = new CustomView(this);
cv1.setId(R.id.custom_view_id_1);
cv2.setId(R.id.custom_view_id_2);
mAdapter = MainPagerAdapter();
mAdapter.addView(cv1);
mAdapter.addView(cv2);
vPager.setAdapter(mAdapter);
}
Run Code Online (Sandbox Code Playgroud)
MainPagerAdapter是一个来自这个问题的接受答案的课程
的源代码 CustomView.java
@Override
protected Parcelable onSaveInstanceState() {
Log.d(TAG, "onSaveInstanceState() called");
}
@Override
protected void onRestoreInstanceState(Parcelable state) {
Log.d(TAG, "onRestoreInstanceState() called");
}
Run Code Online (Sandbox Code Playgroud)
到目前为止,这是我的发现:
onSaveInstanceState() …我有一个顶级ViewGroup,我称它为SliderView,我想在其中检测滑动。这通常可以正常工作,但是一个奇怪的失败仍然存在。
SliderView的本质是重写onInterceptTouchEvent,并且在用户实际滑动后,返回“ true”以防止其他视图占用MotionEvent。这是一段代码:
public class SliderView extends ViewGroup
{
enum MoveState { MS_NONE, MS_HSCROLL, MS_VSCROLL };
private MoveState moveState = MoveState.MS_NONE;
... other code ...
public boolean onInterceptTouchEvent(MotionEvent e)
{
final int action = e.getAction();
switch (action & MotionEvent.ACTION_MASK)
{
case MotionEvent.ACTION_DOWN:
moveState = MoveState.MS_NONE;
break;
case MotionEvent.ACTION_MOVE:
if (moveState == MoveState.MS_NONE)
{
if (motion is horizontal)
{
moveState = MoveState.MS_VSCROLL;
return true;
}
else
moveState = MoveState.MS_VSCROLL; // let child window handl MotionEvent
}
else if (moveState == MoveState.MS_HSCROLL) …Run Code Online (Sandbox Code Playgroud) android scrollview touch-event android-linearlayout motionevent
android ×10
java ×3
collections ×1
dynamic ×1
fragment ×1
motionevent ×1
scrollview ×1
touch-event ×1