简体   繁体   中英

Cannot Go To New Activity When Row Is Clicked

I have been trying to get a option menu to appear when a TextView is clicked. I have been able to accomplish this. However now when I click on the row I cannot go to the next activity.

在此处输入图片说明

This is my code in the MainActivity

//On Long Click On The RecyclerView Item An Alert Dialog Is Opened With The Option To Choose Edit/Delete
        recyclerView.addOnItemTouchListener(new RecyclerTouchListener(this, recyclerView, new RecyclerTouchListener.ClickListener() {
            @Override
            public void onClick(View view, final int position) {
                TextView buttonViewOption = (TextView) view.findViewById(R.id.textViewOptions);
                TextView rowItem = (TextView) view.findViewById(R.id.rowItem);
                buttonViewOption.setOnClickListener(new View.OnClickListener() {

                    @Override
                    public void onClick(View view) {

                        //creating a popup menu
                        PopupMenu popup = new PopupMenu(MainActivity.this, buttonViewOption);
                        //inflating menu from xml resource
                        popup.inflate(R.menu.options_menu);
                        //adding click listener
                        popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
                            @Override
                            public boolean onMenuItemClick(MenuItem item) {
                                switch (item.getItemId()) {
                                    case R.id.menu1:
                                        //handle menu1 click
                                        break;
                                    case R.id.menu2:
                                        break;
                                    case R.id.menu3:
                                        showLeagueDialog(true, leaguesList.get(position), position);
                                        break;
                                    case R.id.menu4:
                                        deleteLeague(position);
                                        break;
                                }
                                return false;
                            }
                        });
                        //displaying the popup
                        popup.show();

                    }
                });
            }
               /*int leagueId = leaguesList.get(position).getId();
                Intent myIntent = new Intent(MainActivity.this, BowlerActivity.class);
                myIntent.putExtra("leagueId", leagueId);
                startActivity(myIntent);
                overridePendingTransition(0, 0);*/
        @Override
        public void onRowClick(View view, int position) {
                    int leagueId = leaguesList.get(position).getId();
                    Intent myIntent = new Intent(MainActivity.this, BowlerActivity.class);
                    myIntent.putExtra("leagueId", leagueId);
                    startActivity(myIntent);
                    overridePendingTransition(0, 0);
                }



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

RecyclerTouchListener.java

public class RecyclerTouchListener implements RecyclerView.OnItemTouchListener {

    private ClickListener clicklistener;
    private GestureDetector gestureDetector;

    public RecyclerTouchListener(Context context, final RecyclerView recycleView, 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 = recycleView.findChildViewUnder(e.getX(), e.getY());
                if (child != null && clicklistener != null) {
                    clicklistener.onLongClick(child, recycleView.getChildAdapterPosition(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.getChildAdapterPosition(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 onRowClick(View view, int position);
        void onLongClick(View view, int position);
    }
}

I have search through many different articles on this site and I have tried several different solutions that members have posted, but I am still unable to to a new activity.

How do you create a onClickListener() that will listen for both a click on the main row, as well as a TextView.

Any assistance would be greatly appreciated.

BolwerAdapter.java

public class BowlerAdapter extends RecyclerView.Adapter<BowlerAdapter.MyViewHolder> {

    private List<Bowler> bowlersList;

    public void notifyDatasetChanged(List<Bowler> newbowlerlist) {
        bowlersList.clear();
        bowlersList.addAll(newbowlerlist);
        super.notifyDataSetChanged();
    }

    public class MyViewHolder extends RecyclerView.ViewHolder {
        private TextView bowlerLeagueId;
        private TextView name;
        private TextView bowlerAverage;
        private TextView bowlerHandicap;
        private TextView timestamp;

        MyViewHolder(View view) {
            super(view);
            bowlerLeagueId = view.findViewById( R.id.tvLeagueId);
            name = view.findViewById(R.id.tvBowlerName);
            bowlerAverage = view.findViewById(R.id.tvBowlerAverage);
            bowlerHandicap = view.findViewById(R.id.tvBowlerHandicap);
            timestamp = view.findViewById(R.id.timestamp);
        }
    }

    BowlerAdapter(Context context, List<Bowler> bowlersList) {
        this.bowlersList = bowlersList;
    }

    @NonNull
    @Override
    public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.from( Objects.requireNonNull( parent ).getContext())
                .inflate(R.layout.listview_bowler, parent, false);

        return new MyViewHolder(itemView);
    }

    @Override
    public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
        Bowler bowler = bowlersList.get(position);

        holder.bowlerLeagueId.setText(bowler.getLeagueId());
        holder.name.setText(bowler.getName());
        if (bowler.getAverage() != "") {
            holder.bowlerAverage.setText(String.format("Bowler Avg: %s", bowler.getAverage()));
        } else {
            holder.bowlerAverage.setText(String.format("Bowler Avg: %s", "0"));
        }
        Integer handicap = Integer.parseInt(bowler.getHandicap());
        if (handicap < 0) {
            holder.bowlerHandicap.setText(String.format("Bowler Handicap: %s", "0"));
        }
        if (bowler.getHandicap() != "" ){
            holder.bowlerHandicap.setText(String.format("Bowler Handicap: %s", bowler.getHandicap()));
        } else {
            holder.bowlerHandicap.setText(String.format("Bowler Handicap: %s", "0"));
        }
        //Formatting And Displaying Timestamp
        holder.timestamp.setText(formatDate(bowler.getTimestamp()));
    }

    @Override
    public int getItemCount() {
        return bowlersList.size();
    }

    //Formatting TimeStamp to 'EEE MMM dd yyyy (HH:mm:ss)'
    //Input  : 2018-05-23 9:59:01
    //Output : Wed May 23 2018 (9:59:01)
    private String formatDate(String dateStr) {
        try {
            SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            Date date = fmt.parse(dateStr);
            SimpleDateFormat fmtOut = new SimpleDateFormat("EEE MMM dd yyyy (HH:mm:ss)");
            return fmtOut.format(date);
        } catch (ParseException ignored) { }

        return "";
    }
}

I have been able to get this to work by setting the onClick() to activate on a TextView. This is not ideal since I seem to have to double tap the text to switch activities.

My code in the MainActivity

recyclerView.addOnItemTouchListener(new RecyclerTouchListener(this, recyclerView, new RecyclerTouchListener.ClickListener() {

            @Override
            public void onRowClick(View view, int position) {
                TextView listviewClick = (TextView) view.findViewById(R.id.tvSeriesName);
                listviewClick.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        int leagueId = leaguesList.get(position).getId();
                        Intent myIntent = new Intent(MainActivity.this, BowlerActivity.class);
                        myIntent.putExtra("leagueId", leagueId);
                        startActivity(myIntent);
                        overridePendingTransition(0, 0);
                    }
                });
            }

            @Override
            public void onClick(View view, final int position) {
                TextView buttonViewOption = (TextView) view.findViewById(R.id.textViewOptions);
                buttonViewOption.setOnClickListener(new View.OnClickListener() {

                    @Override
                    public void onClick(View view) {

                        //creating a popup menu
                        PopupMenu popup = new PopupMenu(MainActivity.this, buttonViewOption);
                        //inflating menu from xml resource
                        popup.inflate(R.menu.options_menu);
                        //adding click listener
                        popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
                            @Override
                            public boolean onMenuItemClick(MenuItem item) {
                                switch (item.getItemId()) {
                                    case R.id.menu1:
                                        //handle menu1 click
                                        break;
                                    case R.id.menu2:
                                        break;
                                    case R.id.menu3:
                                        showLeagueDialog(true, leaguesList.get(position), position);
                                        break;
                                    case R.id.menu4:
                                        deleteLeague(position);
                                        break;
                                }
                                return false;
                            }
                        });
                        //displaying the popup
                        popup.show(); 
                    }
                }); 
            }

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

My listview xml file:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:autofit="http://schemas.android.com/apk/res-auto"
    android:id="@+id/rowItem"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:clickable="true"
    android:focusable="true"
    android:foreground="?attr/selectableItemBackground"
    android:paddingBottom="@dimen/dimen_10"
    android:paddingLeft="@dimen/activity_margin"
    android:paddingRight="@dimen/activity_margin"
    android:paddingTop="@dimen/dimen_10">

    <me.grantland.widget.AutofitTextView
            android:id="@+id/tvSeriesName"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:maxLines="2"
            android:singleLine="true"
            android:text="@string/leagueValue"
            android:textColor="?attr/colorAccent"
            android:textSize="24sp"
            android:textStyle="bold"
            autofit:minTextSize="16sp" />

        <TextView
            android:id="@+id/tvLeagueAverage"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentStart="true"
            android:layout_below="@+id/tvSeriesName"
            android:layout_marginStart="0dp"
            android:text="League Average: 300"
            android:textColor="#000000"
            android:textSize="12sp" />

        <TextView
            android:id="@+id/timestamp"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_below="@+id/tvSeriesName"
            android:layout_centerHorizontal="true"
            android:text="Fri May 18 2018"
            android:textColor="?attr/colorText1"
            android:textSize="10sp"
            android:visibility="gone" />

        <TextView
            android:id="@+id/tvLeagueId"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignEnd="@+id/tvSeriesName"
            android:layout_below="@+id/timestamp"
            android:text="TextView"
            android:textColor="?attr/colorText1"
            android:visibility="gone" />

        <TextView
            android:id="@+id/tvBaseScore"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="TextView"
            android:textColor="?attr/colorText1"
            android:visibility="gone" />

        <TextView
            android:id="@+id/tvBaseScorePercentage"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="TextView"
            android:textColor="?attr/colorText1"
            android:visibility="gone" />

        <View
            android:id="@+id/divider"
            android:layout_width="match_parent"
            android:layout_height="1dp"
            android:layout_alignParentTop="true"
            android:layout_centerHorizontal="true"
            android:layout_marginTop="66dp"
            android:background="?attr/colorAccent" />

        <TextView
            android:id="@+id/textViewOptions"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_alignParentTop="true"
            android:paddingLeft="@dimen/activity_horizontal_margin"
            android:text="&#8942;"
            android:textAppearance="?android:textAppearanceLarge" />

    </RelativeLayout>

However when I use RelativeLayout listviewClick = view.findViewById(R.id.rowItem); I am only able to click on the row , not the options menu.

You need to create a custom adapter class

BowlerAdapter.java

public class BowlerAdapter extends RecyclerView.Adapter<BowlerAdapter.MyViewHolder> {

    private LayoutInflater inflater;

    List<Bowler> data= Collections.emptyList();

    public BowlerAdapter(Context context, List<BowlerAdapter> data) {
       inflater= LayoutInflater.from(context);
        this.data=data;

    }



    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view=inflater.inflate(R.layout.layout_recycler_view_single, parent, false);
        MyViewHolder holder=new MyViewHolder(view);
        return holder;
    }

    @Override
    public void onBindViewHolder(MyViewHolder holder, int position) {

        BowlerAdapter current=data.get(position);
        holder.header.setText(current.header);
        holder.image.setImageResource(current.image);
        //.....
    }

    @Override
    public int getItemCount() {
        return data.size();
    }

    class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{

        CTextView header;
        ImageView image;

        public MyViewHolder(View itemView) {
            super(itemView);
            header= (CTextView) itemView.findViewById(R.id.aap_tv_header);
            image= (ImageView) itemView.findViewById(R.id.aap_img_dog_s);
            itemView.setOnClickListener(this);
        }

        @Override
        public void onClick(View view) {
            int pos = getAdapterPosition();
            BowlerAdapter current=data.get(pos);
            //Now here you can either use switch case or if statement to perform action on the basis of position
        }
    }
}

In MainActivity.java

@Nullable
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView=(RecyclerView) fragView.findViewById(R.id.rv);
adapter=new BowlerAdapter(getActivity(),getData());
recyclerView.setAdapter(adapter);
LinearLayoutManager llm=new LinearLayoutManager(getActivity());
recyclerView.setLayoutManager(llm);
}


public List<Bowler> getData(){
//Here you will return your ArrayList<Bowler>
}

In activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/f1LinearLayout"
    android:orientation="vertical"
   >

    <android.support.v7.widget.RecyclerView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/rv">

    </android.support.v7.widget.RecyclerView>
</LinearLayout>

This is just a sample code. So, you can implement the logic in here. There can be other ways also.

Solution:

Remove the recyclerview.onTouchListener... .. We don't need this anymore.

click listeners on the holder objects works better than that. Please see the following example below:

Similar to holder.bowlerLeagueId.setText(bowler.getLeagueId()); you can also write:

holder.bowlerLeagueId.setOnClickListener(....) {
     ........ (Write here)
}

Then, inside your (Write here) thing, write your code to navigate to next activity.

Similarly you can do it for any holder.viewid.setOnClick etc.

Hope it helps.

May I know that have you register your BowlerActivity in the manifest file? please attach the log as well after you click the view.

I see you initialize the local listener and implement onLongClick & onTouch, but the view you didn't set OnClick event and transfer to customized Listener callback as OnRowClick

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM