0

Im using this guide to implement a ViewPager:

http://mobile.tutsplus.com/tutorials/android/android-user-interface-design-horizontal-view-paging/

This is my main.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:padding="10dp"
android:background="@drawable/gradientbg" >

 <android.support.v4.view.ViewPager
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/viewPager"/>

</LinearLayout>

My main activity:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
setContentView(R.layout.main);

MyPagerAdapter adapter = new MyPagerAdapter();
    ViewPager myPager = (ViewPager)findViewById(R.id.viewPager);
    myPager.setAdapter(adapter);
    myPager.setCurrentItem(1);

    //textviews and other controls that arent located in main.xml will be null for a couple of seconds here

The viewpager uses 2 child xml files as scrollable content. How do i know when the viewpager is complete so that i can make use of the child control, such as textviews etc?

Hope you get the idea, otherwise ill elaborate. Thanks in advance!

public class MyPagerAdapter extends PagerAdapter {

public int getCount() {
    return 2;
}

public Object instantiateItem(View collection, int position) {

    LayoutInflater inflater = (LayoutInflater) collection.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);

    int resId = 0;
    switch (position) {
    case 0:
        resId = R.layout.debug;
        break;
    case 1:
        resId = R.layout.home;
        break;
    }

    View view = inflater.inflate(resId, null);

    ((ViewPager) collection).addView(view, 0);

    return view;
}

@Override
public void destroyItem(View arg0, int arg1, Object arg2) {
    ((ViewPager) arg0).removeView((View) arg2);

}

@Override
public boolean isViewFromObject(View arg0, Object arg1) {
    return arg0 == ((View) arg1);

}

@Override
public Parcelable saveState() {
    return null;
}

}
4

1 に答える 1

0

What I prefer to do in this kind of situation is write a custom View implementation that keeps references to its children which are initialized at creation. (I often just use inner static classes for that.) This helps to keep things modular.

For example:

public class MyView {
  private TextView myTextView;
  private ListView myListView;

  public MyView(Context context) {
    super(context);
    LayoutInflater.from(context).inflate(R.layout.my_layout, this, true);
    myTextView = (TextView) findViewById(R.id.my_textview);
    myListView = (TextView) findViewById(R.id.my_listview);
  }
}

You get the drill. Now you could have a setText(String) method like:

  public void setText(String text) {
    myTextView.setText(text);
  }

In your case you would create two such view classes, one HomeView and one DebugView (or whatever).

You can either create the needed instances beforehand, which seems reasonable if both are being pre-cached by the ViewPager anyway, or you can create them on demand.

The first case (eager instantiation) could look like this:

private HomeView homeView;
private DebugView debugView;

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    homeView = new HomeView(getContext());
    debugView = new DebugView(getContext());

    MyPagerAdapter adapter = new MyPagerAdapter();
    ViewPager myPager = (ViewPager)findViewById(R.id.viewPager);
    myPager.setAdapter(adapter);
    myPager.setCurrentItem(1);
}

You do all the needed initialization in the custom View class' constructor, passing the required information (and/or maybe the savedInstanceState) as required.

Your PagerAdapter's instantiateItem could then look like this:

public Object instantiateItem(ViewGroup container, int position) {

    final View view;
    switch (position) {
    case 0:
       view = debugView;
       break;
    case 1:
       view = homeView;
       break;
    default:
       throw new IllegalStateException("Should not happen");
    }

    container.addView(view, 0);

    return view;
}

(you don't want to use the instantiateItem(View, int) method, it's deprecated and unhandy.)

If you want to instantiate your views on-demand, you you would move the constructor call into the adapter, then you will have to check for null values when accessing the views.

If you can afford to target API 13 and above, you might want to use a FragmentPagerAdapter instead.


To make things look nicer, if you want a PagerAdapter that just servers a really limited number of views which have been pre-created (which you really only want if it's a very small number like 2), you could write it like this:

public class ArrayPagerAdapter extends PagerAdapter {

  private final View[] mViews;

  public ArrayPagerAdapter(View... views) {
      mViews = views;
  }

  @Override
  public int getCount() {
      return mViews.length;
  }

  @Override
  public Object instantiateItem(ViewGroup container, int position) {
      final View view = mViews[position]

      container.addView(view);

      return view;
  }

  @Override
  public void destroyItem(ViewGroup container, int position, Object object) {
      container.removeView((View) object);
  }

  @Override
  public boolean isViewFromObject(View view, Object object) {
      return view == object;
  }

}

which you could then instantiate using

PagerAdapter adapter = new ArrayPagerAdapter(debugView, homeView);
于 2012-07-07T22:31:21.310 に答える