我对回收站视图和碎片有疑问?

Posted

技术标签:

【中文标题】我对回收站视图和碎片有疑问?【英文标题】:I have problem with recycler view and fragments? 【发布时间】:2021-04-16 19:47:10 【问题描述】:

我写了这段代码,但没有显示任何东西,logcat 没有错误

我为此代码设置了三个类Adapterrecyclertouchlistenerfragments 代码...

下面是我的代码

片段代码:

public class VerticalRecyclerFragment extends Fragment 

RecyclerView rcVertical;
static ArrayList<Products> productsArrayList = new ArrayList<>();

public VerticalRecyclerFragment() 
    // Required empty public constructor


@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) 
    View view = inflater.inflate(R.layout.fragment_vertical_recycler,
            container, false);

    showProduct();

    rcVertical = view.findViewById(R.id.rcVertical);
    rcVertical.addOnItemTouchListener(new RecyclerTouchListener(getContext(), rcVertical,
            new RecyclerTouchListener.ClickListener() 
                @Override
                public void onClick(View view, int position) 
                    ProductActivity.products = productsArrayList.get(position);
                    startActivity(new Intent(getActivity(), ProductActivity.class));
                

                @Override
                public void onLongClick(View view, int position) 
                
            ));

    Adapter adapter = new Adapter(productsArrayList, getContext());
    rcVertical.setLayoutManager(new LinearLayoutManager(getActivity()));
    rcVertical.setItemAnimator(new DefaultItemAnimator());
    rcVertical.setAdapter(adapter);

    return view;


public void showProduct() 
    final ProgressDialog loader = ProgressDialog.show(getActivity(),
            "Get products...", "please wait",
            false, false);
    StringRequest request = new StringRequest(Request.Method.POST,
            Config.getProductsWebApi,
            new Response.Listener<String>() 
                @Override
                public void onResponse(String response) 
                    loader.dismiss();
                    productsArrayList.clear();
                    try 
                        JSONObject jsonObject = new JSONObject(response);
                        JSONArray jsonArray = jsonObject.getJSONArray("response");
                        for (int i = 0; i < jsonArray.length(); i++) 
                            JSONObject object = jsonArray.getJSONObject(i);
                            String id = object.getString("id");
                            String name = object.getString("name");
                            String description = object.getString("description");
                            String price = object.getString("price");
                            String photo = object.getString("photo");
                            Products p = new Products(id, name, description, price, photo);
                            productsArrayList.add(p);
                        
                     catch (JSONException e) 
                        e.printStackTrace();
                    
                
            , new Response.ErrorListener() 
        @Override
        public void onErrorResponse(VolleyError error) 
            loader.dismiss();
        
    );
    RequestQueue requestQueue = Volley.newRequestQueue(getActivity());
    requestQueue.add(request);

我在一个类中为适配器编写了这段代码:

public class Adapter extends RecyclerView.Adapter<Adapter.MyHolder> 

ArrayList<Products> ProductsList;
Context context;

public Adapter(ArrayList<Products> productsList, Context context) 
    ProductsList = productsList;
    this.context = context;


@Override
public MyHolder onCreateViewHolder(ViewGroup parent, int viewType) 
    View v = LayoutInflater.from(context).inflate(R.layout.row_layout, parent, false);
    return new MyHolder(v);


@Override
public void onBindViewHolder(MyHolder holder, final int position) 
    Products products = ProductsList.get(position);

    holder.txtName.setText(products.getName());
    holder.txtPrice.setText("$ " + products.getPrice());
    Picasso.get().load(Config.ipValue + "/images/" + products.getPhoto()).into(holder.imgV);
    holder.imgV.setOnClickListener(new View.OnClickListener() 
        @Override
        public void onClick(View v) 
            v.startAnimation(AnimationUtils.loadAnimation(context, android
                    .R.anim.slide_in_left));
        
    );



@Override
public int getItemCount() 
    return ProductsList.size();


class MyHolder extends RecyclerView.ViewHolder 

    TextView txtName;
    TextView txtPrice;
    ImageView imgV;

    public MyHolder(View itemView) 
        super(itemView);

        txtName = itemView.findViewById(R.id.rowTxtProductName);
        txtPrice = itemView.findViewById(R.id.rowTxtPrice);
        imgV = itemView.findViewById(R.id.rowImgProduct);
    

RecyclerTouchListener:

public class RecyclerTouchListener implements RecyclerView.OnItemTouchListener 

private GestureDetector gestureDetector;
private ClickListener clickListener;

public RecyclerTouchListener(Context context, final RecyclerView recyclerView,
                             final ClickListener clickListener) 
    this.clickListener = clickListener;
    gestureDetector = new GestureDetector(context,
            new GestureDetector.SimpleOnGestureListener() 
        @Override
        public boolean onSingleTapUp(MotionEvent e) 
            return true;
        

        @Override
        public void onLongPress(MotionEvent e) 
            View child = recyclerView.findChildViewUnder(e.getX(), e.getY());
            if (child != null && clickListener != null) 
                clickListener.onLongClick(child, recyclerView.getChildPosition(child));
            
        
    );


@Override
public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) 

    View child = rv.findChildViewUnder(e.getX(), e.getY());
    if (child != null && clickListener != null && gestureDetector.onTouchEvent(e)) 
        clickListener.onClick(child,rv.getChildPosition(child));
    
    return false;


@Override
public void onTouchEvent(RecyclerView rv, MotionEvent e) 


@Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) 



public interface ClickListener 
    void onClick(View view, int position);

    void onLongClick(View view, int position);

如果您知道问题出在哪里,请帮我调试它... 谢谢

【问题讨论】:

【参考方案1】:

收到回复时需要notifyDataSetChanged()

将适配器设为类字段

public class VerticalRecyclerFragment extends Fragment 

    RecyclerView rcVertical;
    static ArrayList<Products> productsArrayList = new ArrayList<>();
    Adapter adapter; // <<< Change here

更改初始化(以及适配器对类字段的每次调用)

adapter = new Adapter(productsArrayList, getContext()); // <<< Change here
rcVertical.setLayoutManager(new LinearLayoutManager(getActivity()));
rcVertical.setItemAnimator(new DefaultItemAnimator());
rcVertical.setAdapter(adapter);

当您收到回复时,最后致电notifyDataSetChanged()

public void showProduct() 
    final ProgressDialog loader = ProgressDialog.show(getActivity(),
            "Get products...", "please wait",
            false, false);
    StringRequest request = new StringRequest(Request.Method.POST,
            Config.getProductsWebApi,
            new Response.Listener<String>() 
                @Override
                public void onResponse(String response) 
                    loader.dismiss();
                    productsArrayList.clear();
                    try 
                        JSONObject jsonObject = new JSONObject(response);
                        JSONArray jsonArray = jsonObject.getJSONArray("response");
                        for (int i = 0; i < jsonArray.length(); i++) 
                            JSONObject object = jsonArray.getJSONObject(i);
                            String id = object.getString("id");
                            String name = object.getString("name");
                            String description = object.getString("description");
                            String price = object.getString("price");
                            String photo = object.getString("photo");
                            Products p = new Products(id, name, description, price, photo);
                            productsArrayList.add(p);
                        
                       adapter.notifyDataSetChanged();  // <<< Change here

                     catch (JSONException e) 
                        e.printStackTrace();
                    
                
            ...
        
...


更新:

在收到数据时将适配器附加到RecyclerView

for (int i = 0; i < jsonArray.length(); i++) 
    JSONObject object = jsonArray.getJSONObject(i);
    String id = object.getString("id");
    String name = object.getString("name");
    String description = object.getString("description");
    String price = object.getString("price");
    String photo = object.getString("photo");
    Products p = new Products(id, name, description, price, photo);
    productsArrayList.add(p);

Adapter adapter = new Adapter(productsArrayList, getContext()); // <<< Change here
rcVertical.setAdapter(adapter);  // <<< Change here

【讨论】:

@MHmansouri 请检查答案中的UPDATE 部分..希望它现在可以工作 不,它没有改变,我猜这个问题与另一个地方有关,感谢您的帮助@Zain

以上是关于我对回收站视图和碎片有疑问?的主要内容,如果未能解决你的问题,请参考以下文章

在使用方法创建的回收站视图项目上按下按钮

数据未显示在回收站视图中

水平回收视图中的图像会绕过

Mysql表的碎片整理和空间回收

Java 垃圾回收机制

仅由 'bound_this' 引用的实例不会被垃圾回收