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

Posted

技术标签:

【中文标题】在使用方法创建的回收站视图项目上按下按钮【英文标题】:Getting the button press on recycler view item which is created with method 【发布时间】:2022-01-05 10:05:02 【问题描述】:

我对 android Studio 和 Java 很陌生,所以这可能是一个简单的问题,但我找不到任何解决方案,或者无法使用它们来解决我的问题。

所以我有一个 RecyclerView,当我按下按钮并显示它们时,我可以使用函数“addItems()”从预定义项目列表中插入项目。

这些项目也有 ImageButtons - 它只是一个透明的矩形 - 以获得对它们的单独点击。

这些 ImageButtons 的目的是切换到我在“addItems()”方法中定义的新活动。

但问题是,我无法捕捉 - 但它们会响应点击 - 点击这些项目,而且我无法传递活动类或布局文件。

确切地说,我想使用这些按钮切换到一个新的活动并在那里显示该项目的信息。

这是我的第一个问题,所以如果我需要显示任何代码,请告诉我。

NewsAdapter.java

package com.example.yiyecek2.Activities;

import android.content.Context;
import android.content.Intent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import com.example.yiyecek2.R;

import java.util.List;

public class NewsAdapter extends RecyclerView.Adapter<NewsAdapter.NewsViewHolder>

    Context mContext;
    List<NewsItem> mData;


    public NewsAdapter(Context mContext, List<NewsItem> mData) 
        this.mContext = mContext;
        this.mData = mData;
    

    @NonNull
    @Override
    public NewsViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) 
        View layout;
        layout = LayoutInflater.from(mContext).inflate(R.layout.lyt_restoran,viewGroup,false);
        return new NewsViewHolder(layout);
    
    // Changed below ----------
    @Override
    public void onBindViewHolder(@NonNull NewsViewHolder newsViewHolder, int position) 
        // Bind data here
        newsViewHolder.tvSellerName.setText(mData.get(position).getSellerName());
        newsViewHolder.tvSellerAddress.setText(mData.get(position).getSellerAddress());
        newsViewHolder.ivSellerImage.setImageResource(mData.get(position).getSellerImage());
        newsViewHolder.tvMinCost.setText(mData.get(position).getMinCost());
        newsViewHolder.tvMinTime.setText(mData.get(position).getMinTime());
        newsViewHolder.tvDeliveryCost.setText(mData.get(position).getDeliveryCost());
        newsViewHolder.tvClassToGo.setText(mData.get(position).getClassToGo());
        // Line below is the buttons attached to the items which I aim to use on switching Activities
        newsViewHolder.ibGoSellerPage.setOnClickListener(new View.OnClickListener()
            @Override
            public void onClick(View view) 
                Intent intent = new Intent(SiparisActivity.this, classDominos.class);
                startActivity(intent); // startActivity is marked red
            
        );
    
    // Changed above ----------
    @Override
    public int getItemCount() 
        return mData.size();
    

    public class NewsViewHolder extends RecyclerView.ViewHolder
        TextView tvSellerName, tvSellerAddress, tvMinCost, tvMinTime, tvDeliveryCost, tvClassToGo;
        ImageView ivSellerImage;
        ImageButton ibGoSellerPage;

        public NewsViewHolder(@NonNull View itemView) 
            super(itemView);
            tvSellerName = itemView.findViewById(R.id.tvFoodName);
            tvSellerAddress = itemView.findViewById(R.id.tvFoodDescription);
            ivSellerImage = itemView.findViewById(R.id.ivFoodImage);
            tvMinCost = itemView.findViewById(R.id.tvFoodCost);
            tvMinTime = itemView.findViewById(R.id.tvMinTime);
            tvDeliveryCost = itemView.findViewById(R.id.tvDeliveryCost);
            tvClassToGo = itemView.findViewById(R.id.tvClassToGo);
            ibGoSellerPage = itemView.findViewById(R.id.ibGoSellerPage);
            //int position = getAdapterPosition();
            //Toast.makeText(mContext.getApplicationContext(), "Position is: "+position, Toast.LENGTH_SHORT).show();

        
    

SiparisActivity.java //这是我用上面提到的 ImageButtons 列出餐厅项目的地方。

package com.example.yiyecek2.Activities;

import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.example.yiyecek2.R;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;

import recyclerview.CustomItemAnimator;

public class SiparisActivity extends AppCompatActivity 
    Button btnListRestaurants;
    RecyclerView NewsRecyclerView;
    NewsAdapter newsAdapter;
    List<NewsItem> mData;
    ImageButton ibGoSellerPage;

    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);

        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);

        setContentView(R.layout.activity_siparis);

        // Hide the action bar
        getSupportActionBar().hide();

        NewsRecyclerView = findViewById(R.id.news_rv);
        btnListRestaurants = (Button) findViewById(R.id.buttonListRestaurants);

        NewsRecyclerView.setLayoutManager(new LinearLayoutManager(this));
        NewsRecyclerView.setHasFixedSize(true);
        NewsRecyclerView.setItemAnimator(new CustomItemAnimator());


        // Get clicks on the "List Restaurants"
        btnListRestaurants.setOnClickListener(new View.OnClickListener() 
            int restaurantCount = 0;
            @Override
            public void onClick(View view) 
                Toast toast = Toast.makeText(getApplicationContext(), "Listing Restaurants", Toast.LENGTH_SHORT);
                toast.show();

                Timer timerToTransition;
                timerToTransition = new Timer();
                TimerTask task = new TimerTask() 
                    public void run() 
                        addItems();
                        restaurantCount++;
                        if (restaurantCount > 9)
                        
                            System.out.println(restaurantCount);
                            timerToTransition.cancel(); // Stops the timer when theres 10 Restaurants listed
                        
                    
                ;
                timerToTransition.scheduleAtFixedRate(task,0,300); // waits 300ms before creating a new Restaurant
            
        );

        if (ibGoSellerPage != null) // Check if Restaurant button exists
        
            System.out.println("ON CLICK HERE");
            ibGoSellerPage.setOnClickListener(new View.OnClickListener() 
                @Override
                public void onClick(View view) 
                    System.out.println("ON CLICK HERE");
                
            );
        

        mData = new ArrayList<>();
        // fill list news with pre defined data

        // Adapter ini and setup
        newsAdapter = new NewsAdapter(this,mData);
        NewsRecyclerView.setAdapter(newsAdapter);
        NewsRecyclerView.setLayoutManager(new LinearLayoutManager(this));
    

    private void addItems()
    
        RecyclerView.State state = null;
        int switchInt = 0; // To use in the switch
        // Random integer list to assign switchInt a random value

        int[] intList;
        intList = new int[]0,1,2,3,4,5,6,7;

        // Pick a random int
        Random rand = new Random();
        int rndInt = rand.nextInt(5);

        // Check if the array's index isn't empty(-1)
        while (intList[rndInt] != -1)
        
            switchInt = (int) intList[rndInt];
            intList[rndInt] = -1;
        
        //System.out.println(rndInt);
        switch(switchInt) 
            case 0:
                mData.add(0,new NewsItem("Domino's Pizza","Sarıgöl, Ordu Cd. No:128, 34240 Gaziosmanpaşa/İstanbul",
                        R.drawable.dominos,"32 TL","30 dk.","0 TL","classDominos")); // I'm trying to catch that "classDominos" to use to switch Activity
                break;
            case 1:
                mData.add(0,new NewsItem("Migros","Bağlarbaşı, Küçükköy Yolu Cd., 34245 Gaziosmanpaşa/İstanbul",
                        R.drawable.migroslogo,"32 TL","25 dk.","0 TL", "classDominos"));
                break;
            case 2:
                mData.add(0,new NewsItem("KFC","Yeşilpınar Mah. Şehit Metinkaya Sok Vialand AVM No:11 Mağaza No:237, 34065 Eyüpsultan",
                        R.drawable.kfclogo,"32 TL","35 dk.","3 TL", "classDominos"));
                break;
            case 3:
                mData.add(0,new NewsItem("Popeyes","Yeşilpınar Mah. Şehit Metin Kaya Sok. No:11 K:3 Vialand AVM, 34065",
                        R.drawable.popeyeslogo,"32 TL","35 dk.","3 TL", "classDominos"));
                break;
            case 4:
                mData.add(0,new NewsItem("Mado","İslambey, Hz. Halid Blv. No:43 D:B, 34050 Eyüpsultan/İstanbul",
                        R.drawable.madologo,"32 TL","35 dk.","3 TL", "classDominos"));
                break;
            default:
                break;
        

        System.out.println("Added item");
        newsAdapter.notifyItemInserted(0);
        NewsRecyclerView.getLayoutManager().smoothScrollToPosition(NewsRecyclerView, state, 0);
        
        // Un-commenting the lines below crash the app when "Listing Restaurants" (Creating items)
        //ibGoSellerPage = (ImageButton) findViewById(R.id.ibGoSellerPage);
        /*ibGoSellerPage.setOnClickListener(new View.OnClickListener() 
            @Override
            public void onClick(View view) 
                System.out.println("ON CLICK HERE");
            
        );
        */
    

我可以在分析器中看到各个按钮,但如何捕捉对它们的点击? (你可以看到我按住右边的按钮) Profiler Screenshot

【问题讨论】:

你有一些用于 imageButtons 的 onClickListener 吗?显示您的 recyclver 视图适配器和托管 recyclver 视图的 Activity。 @BabyishTank 我已经用这些编辑了主帖。我尽我所能放置一个 onClickListener,但如果我把它放在活动的 onCreate 事件上,我会崩溃,因为在用户按下按钮列出项目之前该按钮不存在。所以我找不到办法。 【参考方案1】:

我认为你的问题是点击事件发生在另一个视图的屏幕上

通过制作一个透明的矩形,我认为单击转到父视图 尝试测试一下:

 <LinearLayout
 android:id="@+id/layout
 android:layout_
 android:layout_
 android:gravity="center_vertical"
 android:orientation="horizontal">
        
 <ImageButton
 android:layout_
 android:layout_/>
        
</LinearLayout>

处理点击layout 视图如果它有效,因此您需要将透明矩形按钮更改为粗体或另一种方法

最好从您这边添加一些代码,以帮助我们更好地理解问题

【讨论】:

问题是我不知道应该把 onClickListener 放在哪里。如果我将它放在 Activity onCreate 上,则该按钮不存在,因此会引发崩溃。我做了一个 if != null 检查,但仍然无法捕捉到点击。所以它可能不会发生在另一个视图上。 肯定会引发空崩溃,因为按钮属于列表项,所以你必须在你制作的适配器内点击监听器 首先在 viewHolder 中定义 imageButton,就像使用 TextView 一样,然后访问 onBindViewHolder 中的 imageButton 更新了主帖并进行了更改。我按照你说的定义了 ImageButton 并尝试将 onClickListener 放到 onBindViewHolder 但 startActivity 标记为红色,我假设它在这里未定义。 startActivity 需要调用 Activity 上下文,在这里你将上下文传递给适配器,这样你就可以使用你的代码,就像这样 Intent intent = new Intent(SiparisActivity.this, classDominos.class) ; mContext.startActivity(intent);

以上是关于在使用方法创建的回收站视图项目上按下按钮的主要内容,如果未能解决你的问题,请参考以下文章

如何通过在不同的视图控制器上按下按钮来更改 tableview 数据?

按下标签栏项目时如何关闭视图?

从按钮显示新视图按下 Swift UI

如果在对话框上按下按钮,如何启动活动

在Android上按下后退按钮时Runnable线程会发生啥?

在父活动上按下后退按钮