java - ViewPager - 添加或更新卡片时出现问题

标签 java android android-viewpager

我最近开始编写一个使用 ViewPager 的应用程序。我目前坚持向适配器添加新数据。 我的问题是,如果我将新数据添加到我的适配器的数组列表中,将创建 View 但显示奇怪的行为。我可以滚动到它,但是一旦我试图离开我的页面,应用程序就会因溢出错误而崩溃。我调试了应用程序并注意到,不会调用 InstanciateItem() 方法。因此,数据将添加到我的 Arraylist,但不会创建 View 。 当我手动调用 InstanciateItem() 时,除了这次创建了 View 这一事实外,此行为不会改变。

在 mainActivity 的 onCreate() 方法启动期间,我将执行以下代码:

    mViewPager = (ViewPager) findViewById(R.id.viewPager);
    mCardAdapter = new CardPagerAdapter(this, mViewPager);
    mCardAdapter.addCardItem(new CardItem("test1", "ip : 123.123.1.1", "status active"));
    mViewPager.setAdapter(mCardAdapter);

这张卡将被添加,并且在滚动操作期间它们是完整的功能。 稍后在 MainActivity 中,我将执行以下代码:

if(!name.isEmpty() && !IP.isEmpty() && !PW.isEmpty()){

                mCardAdapter.addCardItem(new CardItem(name,IP,"status active"));

                mCardAdapter.instantiateItem(mViewPager,mCardAdapter.mData.size()-1);
                
                System.out.println(mCardAdapter.mViews + " "+ mCardAdapter.mData);
                dialog.dismiss();
            }

这次它的行为与我描述的一样,我是否手动调用 instantiateItem() 并不重要,行为是相同的。

我会把我的 Adapter 的代码发给你,也许你能帮我解决这个问题。

public class CardPagerAdapter extends PagerAdapter implements CardAdapter {

    ViewPager viewPager;
    MainActivity mainActivity;

    public List<CardView> mViews;
    public List<CardItem> mData;
    private float mBaseElevation;

    public CardPagerAdapter(MainActivity mainActivity, ViewPager viewPager) {
        mData = new ArrayList<>();
        mViews = new ArrayList<>();
        this.mainActivity = mainActivity;
        this.viewPager = viewPager;
    }

    public void addCardItem(CardItem item) {
        mViews.add(null);
        mData.add(item);
        notifyDataSetChanged();
    }

    public void deleteCardItem(int position){
        mData.remove(position);
        mViews.set(position, null);
        notifyDataSetChanged();
    }

    public float getBaseElevation() {
        return mBaseElevation;
    }

    @Override
    public CardView getCardViewAt(int position) {
        return mViews.get(position);
    }

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

    @Override
    public int getNumberOfCards() {return mViews.size();}

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

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

    @Override
    public int getItemPosition(@NonNull Object object) {
        int position = mViews.indexOf(object);
        if(position == -1){
            return POSITION_NONE;
        }else{
            return position;
        }
    }


    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        Button deleteButton;
        Button editButton;

        View view = LayoutInflater.from(container.getContext()).inflate(R.layout.device_card_layout,      
        container, false);

        deleteButton = view.findViewById(R.id.deleteButton);
        editButton = view.findViewById(R.id.editButton);

        deleteButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                System.out.println("fetus deletus");
                deleteCardOperation(viewPager.getCurrentItem(), container);

            }
        });

        editButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                System.out.println("edit");
                int currentCard = viewPager.getCurrentItem();
            }
        });

        container.addView(view);
        bind(mData.get(position), view);

        CardView cardView = (CardView) view.findViewById(R.id.itemCard);

        if (mBaseElevation == 0) {
            mBaseElevation = cardView.getCardElevation();
        }

        cardView.setMaxCardElevation(mBaseElevation * MAX_ELEVATION_FACTOR);
        mViews.set(position, cardView);

        return view;
    }

    private void bind(CardItem item, View view) {
        TextView titleTextView = (TextView) view.findViewById(R.id.itemText);
        TextView ipTextView = (TextView) view.findViewById(R.id.itemIPAdress);
        TextView statusView = (TextView) view.findViewById(R.id.itemActiveStatus);
        titleTextView.setText(item.getName());
        ipTextView.setText(item.getIp());
        statusView.setText(item.getStatus());
    }

    private void deleteCardOperation(int position, ViewGroup desV){

        CardItem x = mData.get(position);

        AlertDialog.Builder builder = new AlertDialog.Builder(mainActivity, 
        android.R.style.Theme_Material_Dialog_Alert);
        builder.setTitle("Confirm");
        builder.setMessage("Are you sure you want to delete this device: "+ x.getName() + " ?");
        builder.setPositiveButton("YES", new DialogInterface.OnClickListener() {
        
        public void onClick(DialogInterface dialog, int which) {
            deleteCardItem(position);
            dialog.dismiss();
        }
    });

    builder.setNegativeButton("NO", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            // Do nothing
            dialog.dismiss();
        }
    });

    AlertDialog alert = builder.create();
    alert.show();



}


}

我的问题是,我不明白为什么代码的行为如此不同。我刚刚在 StackOverflow 上搜索了这里提出的许多建议,但找不到适合我的结论。也许我只是错过了一些东西。如果有任何建议或帮助解决我的问题,我会很高兴。

最佳答案

我问这个问题已经有几天了,但我仍然没有设法让 ViewPager 工作。问题似乎是,ViewPager 本身不再由谷歌提供服务。 ViewPager 在更新处理方面存在问题。但是这个问题不会被修复,因为它不会被谷歌更新。他们只是创建了基于recyclerView 的ViewPager2 结构。 我尝试切换到新的 ViewPager,它直接工作。动态添加、删除或更新卡片没有问题。这非常简单。

对于遇到同样问题的每个人,我建议切换到 ViewPager2。它比旧的 ViewPager 方便多了。此外,新的 ViewPager2 与旧的没有太大区别,除了更改了后端。

关于java - ViewPager - 添加或更新卡片时出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64773534/

相关文章:

java - 高级安装程序中的 ODBC 驱动程序

android - 将 Android 的 SlidingPaneLayout 与 ViewPager 结合使用

android - FragmentStatePagerAdapter中 "isViewFromObject (View view, Object object)"的作用是什么?

java - 如何从 fragment 中的RecyclerView获取有关复选框的信息

android - 膨胀 View 返回旧的膨胀结果

android - 嵌套viewpager的setCurrentItem

java - 单击操作栏中的共享应用程序链接时出现问题

java - World Wind Java SDK离线使用方法

java - 如何在任何在线服务器上部署 Spring 框架后端和 Angular 2 前端应用程序?

android - 在android中模拟内存不足