java - 当 layoutManager 的 scrollToPositionWithOffset 时项目的 recyclerView 之间空白

标签 java android android-recyclerview

我的 RecyclerView 有一个小问题。 事实上,它在他的每个项目中都包含另一个 RecyclerView,当我尝试在我的全局 RecyclerView(行上的监听器 onClick)上使用 LinearLayoutManager 滚动时,第一个和最后一个项目的第二个 RecyclerView 的项目之间出现空白。

A screen of the problem (sorry for my crappy english).

我的第一个 RecyclerView 适配器:

    package com.ylly.hypred.process.adapter;

/**
 * Created by YLLY on 24/06/2015.
 */

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.Toast;

import com.ylly.hypred.R;
import com.ylly.hypred.custom.HypredToast;
import com.ylly.hypred.custom.MyTextView;
import com.ylly.hypred.custom.RecyclerItemClickListener;
import com.ylly.hypred.dao.Etape;
import com.ylly.hypred.dao.Produit;
import com.ylly.hypred.dao.Protocole;
import com.ylly.hypred.db.HypredDbManager;
import com.ylly.hypred.process.atelierProcess.AtelierProcessModeleUn;
import com.ylly.hypred.process.recyclerView.SpacesItemDecoration;

import org.solovyev.android.views.llm.LinearLayoutManager;

import java.util.ArrayList;
import java.util.List;

public class AdapterProtocole extends RecyclerView.Adapter<AdapterProtocole.ViewHolder> implements AdapterEtape.clickOnProductListener {
    private ArrayList<Protocole> protocoleArrayList;
    private Context context;
    private clickOnProductListener mCallback;

    public AdapterProtocole(ArrayList<Protocole> protocoleArrayList, Context context) {
        this.protocoleArrayList = protocoleArrayList;
        this.context = context;
    }

    public interface clickOnProductListener {
        void appelProduit(long productId);

        void ajouterAllProduit(ArrayList<Produit> produitArrayList);

        void ajouterProduit(Produit produit);
    }

    // Create new views (invoked by the layout manager)
    @Override
    public AdapterProtocole.ViewHolder onCreateViewHolder(ViewGroup parent,
                                                          int viewType) {
        // create a new view
        View itemLayoutView = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.item_layout_process_protocole, null);

        // create ViewHolder

        ViewHolder viewHolder = new ViewHolder(itemLayoutView);
        return viewHolder;
    }

    // Replace the contents of a view (invoked by the layout manager)
    @Override
    public void onBindViewHolder(ViewHolder viewHolder, int position) {

        // - get data from your itemsData at this position
        // - replace the contents of the view with that itemsData

        View view = new View(context);
        viewHolder.labelProtocoleTextView.setText(protocoleArrayList.get(position).getName());
        viewHolder.produitsRecyclerView.addItemDecoration(new SpacesItemDecoration(0, 0, 0, 10));
        viewHolder.produitsRecyclerView.setLayoutManager(new LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false));

        final ArrayList<Etape> fEtapeArrayList = new ArrayList<>();

        Log.d("AdapterProtocole", "id des étapes du protocole " + protocoleArrayList.get(position).getName() + " = " +
        protocoleArrayList.get(position).getEtapeId() + "," +
                protocoleArrayList.get(position).getEtapeTwoId() + "," +
                protocoleArrayList.get(position).getEtapeThreeId() + "," +
                protocoleArrayList.get(position).getEtapeFourId() + "," +
                protocoleArrayList.get(position).getEtapeFiveId() + "," +
                protocoleArrayList.get(position).getEtapeSixId() + ".");

        String test = "listes etapes dispo :";
        List<Etape> etapes = HypredDbManager.getDbManager().getEtapeDbManager().getAllEtape();
        for(int i=0; i<etapes.size(); i++) {
            test += etapes.get(i).getId() + ",";
        }
        Log.d("AdapterProtocole", test);
        if (HypredDbManager.getDbManager().getEtapeDbManager()
                .getEtapeById(protocoleArrayList.get(position).getEtapeId()) != null) {
            fEtapeArrayList.add(HypredDbManager.getDbManager().getEtapeDbManager()
                    .getEtapeById(protocoleArrayList.get(position).getEtapeId()));
        }
        if (HypredDbManager.getDbManager().getEtapeDbManager()
                .getEtapeById(protocoleArrayList.get(position).getEtapeTwoId()) != null) {
            fEtapeArrayList.add(HypredDbManager.getDbManager().getEtapeDbManager()
                    .getEtapeById(protocoleArrayList.get(position).getEtapeTwoId()));
        }
        if (HypredDbManager.getDbManager().getEtapeDbManager()
                .getEtapeById(protocoleArrayList.get(position).getEtapeThreeId()) != null) {
            fEtapeArrayList.add(HypredDbManager.getDbManager().getEtapeDbManager()
                    .getEtapeById(protocoleArrayList.get(position).getEtapeThreeId()));
        }
        if (HypredDbManager.getDbManager().getEtapeDbManager()
                .getEtapeById(protocoleArrayList.get(position).getEtapeFourId()) != null) {
            fEtapeArrayList.add(HypredDbManager.getDbManager().getEtapeDbManager()
                    .getEtapeById(protocoleArrayList.get(position).getEtapeFourId()));
        }
        if (HypredDbManager.getDbManager().getEtapeDbManager()
                .getEtapeById(protocoleArrayList.get(position).getEtapeFiveId()) != null) {
            fEtapeArrayList.add(HypredDbManager.getDbManager().getEtapeDbManager()
                    .getEtapeById(protocoleArrayList.get(position).getEtapeFiveId()));
        }
        if (HypredDbManager.getDbManager().getEtapeDbManager()
                .getEtapeById(protocoleArrayList.get(position).getEtapeSixId()) != null) {
            fEtapeArrayList.add(HypredDbManager.getDbManager().getEtapeDbManager()
                    .getEtapeById(protocoleArrayList.get(position).getEtapeSixId()));
        }
        Log.d("AdapterProtocole", Integer.toString(fEtapeArrayList.size()));

        final AdapterEtape etapeAdapter = new AdapterEtape(fEtapeArrayList, view.getContext());
        etapeAdapter.setClickOnProductListener(new AdapterEtape.clickOnProductListener() {
            @Override
            public void appelerProduit(long produitId) {
                mCallback.appelProduit(produitId);
            }

            @Override
            public void ajouterProduitSelection(Produit produit) {
                mCallback.ajouterProduit(produit);
            }
        });

        viewHolder.produitsRecyclerView.setAdapter(etapeAdapter);

        viewHolder.imageViewPanierSelectionAll.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ArrayList<Produit> produits = new ArrayList<>();
                for (int i = 0; i < fEtapeArrayList.size(); i++) {
                    produits.add((fEtapeArrayList.get(i).getProduit()));
                }
                mCallback.ajouterAllProduit(produits);
                HypredToast.makeText(context, "Produits ajoutés au panier avec succès.", Toast.LENGTH_SHORT).show();
            }
        });
    }

    // inner class to hold a reference to each item of RecyclerView
    public static class ViewHolder extends RecyclerView.ViewHolder {

        public MyTextView labelProtocoleTextView;
        public RecyclerView produitsRecyclerView;
        public ImageView imageViewPanierSelectionAll;

        public ViewHolder(View itemLayoutView) {
            super(itemLayoutView);
            labelProtocoleTextView = (MyTextView) itemLayoutView.findViewById(R.id.item_layout_protocole_label_text_view);
            produitsRecyclerView = (RecyclerView) itemLayoutView.findViewById(R.id.item_layout_protocole_recycler_view);
            imageViewPanierSelectionAll = (ImageView) itemLayoutView.findViewById(R.id.item_layout_process_protocole_panier_rouge);
        }
    }


    // Return the size of your itemsData (invoked by the layout manager)
    @Override
    public int getItemCount() {
        return protocoleArrayList.size();
    }

    @Override
    public void appelerProduit(long produitId) {

    }

    public void setClickOnProductListener(clickOnProductListener callback) {
        mCallback = callback;
    }

    @Override
    public void ajouterProduitSelection(Produit produit) {

    }
}

我的 RecyclerView 内部:

    package com.ylly.hypred.process.adapter;

/**
 * Created by YLLY on 20/07/2015.
 */

import android.content.Context;
import android.graphics.Paint;
import android.support.v4.content.ContextCompat;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.Toast;

import com.ylly.hypred.R;
import com.ylly.hypred.custom.HypredToast;
import com.ylly.hypred.custom.MyTextView;
import com.ylly.hypred.dao.Etape;
import com.ylly.hypred.dao.Produit;
import com.ylly.hypred.db.HypredDbManager;
import com.ylly.hypred.process.atelierProcess.AtelierProcessModeleUn;

import java.util.ArrayList;

public class AdapterEtape extends RecyclerView.Adapter<AdapterEtape.ViewHolder> {
    private ArrayList<Etape> etapeArrayList;
    private Context context;
    private clickOnProductListener mCallback;

    public interface clickOnProductListener {
        void appelerProduit(long produitId);
        void ajouterProduitSelection(Produit produit);
    }

    public AdapterEtape(ArrayList<Etape> etapeArrayList, Context context) {
        this.etapeArrayList = etapeArrayList;
        this.context = context;
    }

    // Create new views (invoked by the layout manager)
    @Override
    public AdapterEtape.ViewHolder onCreateViewHolder(ViewGroup parent,
                                                      int viewType) {
        // create a new view
        View itemLayoutView = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.item_layout_process_etape, null);

        // create ViewHolder

        ViewHolder viewHolder = new ViewHolder(itemLayoutView);
        return viewHolder;
    }

    // Replace the contents of a view (invoked by the layout manager)
    @Override
    public void onBindViewHolder(final ViewHolder viewHolder, final int position) {

        // - get data from your itemsData at this position
        // - replace the contents of the view with that itemsData

        viewHolder.labelEtapeTextView.setText(etapeArrayList.get(position).getTexte_etape());
        if(HypredDbManager.getDbManager().getProductDbManager().
                getProduitById(etapeArrayList.get(position).getProduitId())!=null) {
            viewHolder.labelProduitTextView
                    .setText(HypredDbManager.getDbManager().getProductDbManager().
                            getProduitById(etapeArrayList.get(position).getProduitId()).getNom_produit());
        }
        viewHolder.labelProduitTextView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mCallback.appelerProduit(etapeArrayList.get(position).getProduitId());
            }
        });
        viewHolder.descriptifTextView.setText(etapeArrayList.get(position).getTemps() + "/" +
                etapeArrayList.get(position).getConcentration() + "/" + etapeArrayList.get(position).getTemperature());
        int temp = 1 + position;
        if (etapeArrayList.size() == temp && etapeArrayList.get(position).getRincage()) {
            viewHolder.imageViewEtapeSuivante.setImageDrawable(ContextCompat.getDrawable(context, R.drawable.hypred_protocole_vague_finale));
        } else if(etapeArrayList.get(position).getRincage()) {
            viewHolder.imageViewEtapeSuivante.setImageDrawable(ContextCompat.getDrawable(context, R.drawable.hypred_protocole_vague));
        }

        viewHolder.imageViewPanierSelection.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mCallback.ajouterProduitSelection(etapeArrayList.get(position).getProduit());
                HypredToast.makeText(context, "Produit ajouté au panier avec succès.", Toast.LENGTH_SHORT).show();
            }
        });
    }

    // inner class to hold a reference to each item of RecyclerView
    public static class ViewHolder extends RecyclerView.ViewHolder {

        public MyTextView labelEtapeTextView;
        public MyTextView labelProduitTextView;
        public MyTextView descriptifTextView;
        public ImageView imageViewEtapeSuivante;
        public ImageView imageViewPanierSelection;

        public ViewHolder(View itemLayoutView) {
            super(itemLayoutView);
            labelEtapeTextView = (MyTextView) itemLayoutView.findViewById(R.id.item_layout_etape_label_etape_text_view);
            labelProduitTextView = (MyTextView) itemLayoutView.findViewById(R.id.item_layout_etape_label_produit_text_view);
            descriptifTextView = (MyTextView) itemLayoutView.findViewById(R.id.item_layout_etape_descriptif_text_view);
            labelProduitTextView.setPaintFlags(labelProduitTextView.getPaintFlags() | Paint.UNDERLINE_TEXT_FLAG);
            imageViewEtapeSuivante = (ImageView) itemLayoutView.findViewById(R.id.item_layout_etape_vague_image_view);
            imageViewPanierSelection = (ImageView) itemLayoutView.findViewById(R.id.item_layout_etape_panier_image_view);
        }
    }

    public Etape getEtape(int position) {
        Etape etape = etapeArrayList.get(position);

        return etape;
    }


    // Return the size of your itemsData (invoked by the layout manager)
    @Override
    public int getItemCount() {
        return etapeArrayList.size();
    }

    public void setClickOnProductListener(clickOnProductListener callback) {
        mCallback = callback;
    }

}

我定义 Protocol RecyclerView 和滚动行的函数:

public void initProtocole(View v, final FragmentProtocoles protocoleFragment, ArrayList<Protocole> protocoleArrayList) {
super.initProtocole(v, protocoleFragment, protocoleArrayList);

initFrameLayout(v, R.id.fragment_protocole_container, R.layout.view_process_protocole_rep);

ArrayList<Protocole> fProtocoleArrayList = new ArrayList<>();
for (int i = 0; i < protocoleArrayList.size(); i++) {
    fProtocoleArrayList.add(protocoleArrayList.get(i));
}

final RecyclerView recyclerView = (RecyclerView) v.findViewById(R.id.protocole_rep_recycler_view);
recyclerView.addItemDecoration(new SpacesItemDecoration(25, 25, 25, 25));
final LinearLayoutManager mLayoutManager = new LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false);
recyclerView.setLayoutManager(mLayoutManager);
AdapterProtocole adapterProtocole = new AdapterProtocole(fProtocoleArrayList, v.getContext());
adapterProtocole.setClickOnProductListener(new AdapterProtocole.clickOnProductListener() {
    @Override
    public void appelProduit(long productId) {
        protocoleFragment.appelProduit(HypredDbManager.getDbManager().getProductDbManager().getProduitById(productId));
    }

    @Override
    public void ajouterAllProduit(ArrayList<Produit> produitArrayList) {
        for (int i = 0; i < produitArrayList.size(); i++) {
            SelectionManager.getInstance().addProductToSelection(produitArrayList.get(i));
        }
    }

    @Override
    public void ajouterProduit(Produit produit) {
        SelectionManager.getInstance().addProductToSelection(produit);
    }
});
recyclerView.setAdapter(adapterProtocole);

ImageView imageViewProtocoleFlecheGauche = (ImageView) v.findViewById(R.id.protocole_rep_fleche_gauche);
imageViewProtocoleFlecheGauche.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        RecyclerViewPositionHelper recyclerViewPositionHelper = RecyclerViewPositionHelper.createHelper(recyclerView);
        int firstVisibleItem = recyclerViewPositionHelper.findFirstCompletelyVisibleItemPosition();
        if (firstVisibleItem != 0) {
            mLayoutManager.scrollToPositionWithOffset(firstVisibleItem - 1, 0);
        }
    }
});

ImageView imageViewProtocoleFlecheDroite = (ImageView) v.findViewById(R.id.protocole_rep_fleche_droite);
imageViewProtocoleFlecheDroite.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        RecyclerViewPositionHelper recyclerViewPositionHelper = RecyclerViewPositionHelper.createHelper(recyclerView);
        int lastVisibleItem = recyclerViewPositionHelper.findLastCompletelyVisibleItemPosition();
        int firstVisibleItem = recyclerViewPositionHelper.findFirstCompletelyVisibleItemPosition();
        if (lastVisibleItem != recyclerViewPositionHelper.getItemCount() - 1) {
            mLayoutManager.scrollToPositionWithOffset(firstVisibleItem + 1, 0);
        }
    }
});
}

提前致谢:)

最佳答案

我也面临同样的问题,你需要改变你的 RecyclerView adapter::

现在在你的代码中是这样的::

 // Create new views (invoked by the layout manager)
    @Override
    public AdapterEtape.ViewHolder onCreateViewHolder(ViewGroup parent,
                                                      int viewType) {
        // create a new view
        View itemLayoutView = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.item_layout_process_etape, null);

        // create ViewHolder

        ViewHolder viewHolder = new ViewHolder(itemLayoutView);
        return viewHolder;
    }

你需要像这样改变::

 // Create new views (invoked by the layout manager)
    @Override
    public AdapterEtape.ViewHolder onCreateViewHolder(ViewGroup parent,
                                                      int viewType) {
        // create a new view
        View itemLayoutView = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.item_layout_process_etape, parent, false);

        // create ViewHolder

        ViewHolder viewHolder = new ViewHolder(itemLayoutView);
        return viewHolder;
    }

关于java - 当 layoutManager 的 scrollToPositionWithOffset 时项目的 recyclerView 之间空白,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32245769/

相关文章:

android - 如何让设备休眠 (Android)

java - 意外的 boolean 结果

Java 集合

java - 安卓 :xml file not working

android - BLE 扫描回调的类加载期间的 NoClassDefFoundError

android - RecyclerView 移除动画错误

android - 回收站查看 : listen to padding click events

android - 滚动 |始终输入折叠系统任务栏,而不是我的工具栏

java - 相同的数据集,两个不同的 JTable

java - 为什么 Eclipse 不允许我正确创建子文件夹?