在Android中正确实现PagerAdapter

11
我在实现自定义 PagerAdapter 并将其与 ViewPager 一起使用时遇到了问题。 这个示例的 PagerAdapter 有10个项目,每个项目都是一个带有它的索引作为文本的按钮。 当我运行我的程序时,我看到一个带有文本“1”的按钮而不是“0”。当我向其他项目滑动时,我只得到空白视图。当我向后滑动时,有时会看到一个带有某个数字的按钮,但它会消失(可能被销毁并从容器中删除),有时候我会看到一个带有数字的按钮,但该数字在滑动后会更改(我认为我创建了一个新的 Button,并将其添加到容器中,由于某些原因,viewpager 显示了这个新的 button)。
如何修复这个实现?我没有看到示例中的区别。
我的 PagerAdapter 实现:
public class MyPagerAdapter extends PagerAdapter {

    @Override
    public int getCount() {
        return 10;
    }

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

    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        Button button = new Button(container.getContext());
        ViewGroup.LayoutParams params = new ActionBar.LayoutParams(-1,-1);
        button.setLayoutParams(params);
        button.setText(String.valueOf(position));
        container.addView(button);
        return button;
    }

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

我的活动:

public class MainActivity extends ActionBarActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ViewPager pager = (ViewPager) findViewById(R.id.pager);
        pager.setAdapter(new MyPagerAdapter());
    }
}

3
isViewFromObject()方法中,将o.getClass()==view.getClass()替换为o==view - corsair992
3个回答

15

这是完整的代码:

XML布局:

<LinearLayout 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"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:orientation="vertical"
    tools:context="com.example.androidviewpagerapp.MainActivity" >

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

</LinearLayout>

MyPagerAdapter类:

import android.support.v4.view.PagerAdapter;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.Toast;

public class MyPagerAdapter extends PagerAdapter {

    @Override
    public int getCount() {
        return 10;
    }

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

    @Override
    public Object instantiateItem(final ViewGroup container, int position) {
        Button button = new Button(container.getContext());
        ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        button.setLayoutParams(params);
        button.setText(String.valueOf(position));

        final int page = position;
        button.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                Toast.makeText(container.getContext(), "You clicked: " + page + ". page.", Toast.LENGTH_SHORT).show();
            }
        });

        container.addView(button);
        return button;
    }

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

MainActivity:

import android.support.v4.view.ViewPager;
import android.app.Activity;
import android.os.Bundle;

public class MainActivity extends Activity {
    ViewPager viewPager;
    MyPagerAdapter myPagerAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        viewPager = (ViewPager)findViewById(R.id.pager);
        myPagerAdapter = new MyPagerAdapter();
        viewPager.setAdapter(myPagerAdapter);
    }
}
你会发现按钮是全屏的。为了避免这种情况,你需要创建一些布局(例如LinearLayout),并将按钮添加到该布局中。
示例:
import android.support.v4.view.PagerAdapter;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.Toast;

public class MyPagerAdapter extends PagerAdapter {

    @Override
    public int getCount() {
        return 10;
    }

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

    @Override
    public Object instantiateItem(final ViewGroup container, int position) {
        Button button = new Button(container.getContext());
        ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        button.setLayoutParams(params);
        button.setText(String.valueOf(position));

        LinearLayout layout = new LinearLayout(container.getContext());
        layout.setOrientation(LinearLayout.VERTICAL);
        ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(
                ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);

        //add buton to layout
        layout.addView(button);

        final int page = position;
        button.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                Toast.makeText(container.getContext(), "You clicked: " + page + ". page.", Toast.LENGTH_SHORT).show();
            }
        });
        //to container add layout instead of button
        container.addView(layout);
        //return layout instead of button
        return layout;
    }

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        //cast to LinearLayout
        container.removeView((LinearLayout)object);
    }
}

你得到答案了吗? - Pravinsingh Waghela
ViewPager是否在MainActivity的XML文件中? - pewpew
请注意,ViewPager的高度与其项的高度不相等。项目显示为截断且高度不正确。我该如何解决这个问题?以下是我的问题链接: https://dev59.com/acDqa4cB1Zd3GeqPVxjE - Ahmed Elsayed

6
如果您想填充Pager中的视图,您必须实现两种方法。 instantiateItem和destroyItem
public class DialogPagerAdapter extends PagerAdapter {

    private Context mContext;

    //view inflating..
    @Override
    public Object instantiateItem(ViewGroup collection, int position) {
        LayoutInflater inflater = LayoutInflater.from(mContext);
        ViewGroup layout = (ViewGroup) inflater.inflate(R.layout.account_dialog_signin_viewpagers,
                collection, false);

        TextView tvLabel = (TextView) layout.findViewById(R.id.textView);
        switch (position) {
            case 0:
                tvLabel.setText("Log In");
                tvLabel.setOnClickListener(new View.OnClickListener() {

                    @Override
                    public void onClick(View v) {
                    }
                });
                break;
            case 1:
                tvLabel.setText("Sign Up");
                tvLabel.setOnClickListener(new View.OnClickListener() {

                    @Override
                    public void onClick(View v) {
                    }
                });
                break;
            case 2:
                tvLabel.setText("Send Reset Link");
                tvLabel.setOnClickListener(new View.OnClickListener() {

                    @Override
                    public void onClick(View v) {
                        //onOptionClickForgot.OnOptionClick();
                    }
                });
                break;
        }

        collection.addView(layout);
        return layout;
    }

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

    @Override
    public int getCount() {
        return 3;
    }

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

只需像这样调用它:

viewPager.setAdapter(new DialogPagerAdapter);

xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="@dimen/dialog_button_height"
    android:paddingLeft="@dimen/dimen_2"
    android:paddingRight="@dimen/dimen_2"
    android:minHeight="@dimen/dialog_button_height">

    <TextView
        android:id="@+id/textView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_centerInParent="true"
        android:gravity="center"
        android:text="@string/app_name"
        android:textColor="@color/white"
        android:textSize="@dimen/text_size_medium" />
</RelativeLayout>

我认为你必须至少覆盖这四个方法,对吗? - n00dles

0
这里我发布一个 ViewPagerAdapter,它连接了 TabLayoutViewPager
public class ViewPagerAdapter extends FragmentPagerAdapter {

    ArrayList<String> titleList = new ArrayList<>();
    List<Fragment> fragment = new ArrayList<>();

    public void addFragment(String title, Fragment fragment) {
        this.titleList.add(title);
        this.fragment.add(fragment);
    }

    public ViewPagerAdapter(FragmentManager fm) {
        super(fm);
    }

    @NonNull
    @Override
    public Fragment getItem(int position) {
        return fragment.get(position);
    }

    @Override
    public int getCount() {
        return titleList.size();
    }

    public CharSequence getPageTitle(int position) {
        return titleList.get(position);
    }
}

如何使用 ViewPagerAdapter

 ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
 adapter.addFragment("TAB 1", new YOUR_FRAGMENT1());
 adapter.addFragment("TAB 2", new YOUR_FRAGMENT2());
 // Keep adding fragments.
 viewPager.setAdapter(adapter);
 tabLayout.setupWithViewPager(viewPager);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接