[Android Studio]如何从Fragment中嵌套的Recycleview启动一个Activity?
Posted
技术标签:
【中文标题】[Android Studio]如何从Fragment中嵌套的Recycleview启动一个Activity?【英文标题】:[Android Studio]How to start an Activity from a nested Recycleview in a Fragment? 【发布时间】:2021-09-05 21:50:15 【问题描述】:我想在我的 RecycleView 中单击一个自定义对象,然后它会启动一个新的 Activity 包含有关所单击对象的数据,但单击时我没有得到任何响应。
我尝试关注this 问题,但要么我做错了,要么它不起作用。
笑话类别
package com.example.jokestarapplication;
import android.os.Parcel;
import android.os.Parcelable;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
public class JokeCategory implements Parcelable
private String name;
private List<Joke> jokes;
public JokeCategory(String name)
this.name = name;
this.jokes= new ArrayList<>();
protected JokeCategory(Parcel in)
name=in.readString();
in.readList(jokes,List.class.getClassLoader());
public JokeCategory(String name, List<Joke> jokes)
this.name = name;
this.jokes = jokes;
public static final Creator<JokeCategory> CREATOR = new Creator<JokeCategory>()
@Override
public JokeCategory createFromParcel(Parcel in)
return new JokeCategory(in);
@Override
public JokeCategory[] newArray(int size)
return new JokeCategory[size];
;
public String getName()
return name;
public String getJokeNumString()
return String.valueOf(jokes.size());
public List<Joke> getJokes()
return jokes;
@Override
public String toString()
return name;
public void addJoke(Joke joke)
jokes.add(joke);
@Override
public int describeContents()
return 0;
@Override
public void writeToParcel(Parcel dest, int flags)
dest.writeString(name);
dest.writeList(jokes);
CategoryListAdapter
package com.example.jokestarapplication;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.List;
public class CategoryListAdapter extends RecyclerView.Adapter<CategoryListAdapter.CategoryViewHolder>
private List<JokeCategory> mItems;
private Context mContext;
private ListItemClickListener mListItemClickListener;
public CategoryListAdapter(List<JokeCategory> mItems, Context mContext, ListItemClickListener mListItemClickListener)
this.mItems = mItems;
this.mContext = mContext;
this.mListItemClickListener = mListItemClickListener;
@Override
public int getItemViewType(final int position)
return R.layout.category_list_item;
@NonNull
@Override
public CategoryViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType)
Context context = parent.getContext();
mContext = context;
LayoutInflater inflater = LayoutInflater.from(context);
View view = inflater.inflate(R.layout.category_list_item, parent, false);
return new CategoryViewHolder(view);
@Override
public void onBindViewHolder(@NonNull CategoryViewHolder holder, int position)
holder.bind(position);
@Override
public int getItemCount()
return (mItems==null) ? 0 : mItems.size();
interface ListItemClickListener
void onListItemClick(JokeCategory item);
public void setOnListItemClickListener(ListItemClickListener listItemClickListener)
mListItemClickListener = listItemClickListener;
public class CategoryViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener
private TextView tvCatName, tvCatNum;
public CategoryViewHolder(@NonNull View itemView)
super(itemView);
tvCatName = itemView.findViewById(R.id.tvCatName);
tvCatNum = itemView.findViewById(R.id.tvCatNum);
public TextView getTvCatName()
return tvCatName;
public TextView getTvCatNum()
return tvCatNum;
public void bind(int position)
tvCatName.setText(mItems.get(position).getName());
tvCatNum.setText(mItems.get(position).getJokeNumString());
@Override
public void onClick(View v)
if (mListItemClickListener!=null)
int clickedIndex = getAdapterPosition();
JokeCategory jokeCategory = mItems.get(clickedIndex);
mListItemClickListener.onListItemClick(jokeCategory);
主片段
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import java.util.LinkedList;
import java.util.List;
public class MainFragment extends Fragment implements CategoryListAdapter.ListItemClickListener
private CategoryListAdapter mAdapter;
private RecyclerView rvcategories;
private List<JokeCategory> categories;
private onCategoryITemSelected listener;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
View view = inflater.inflate(R.layout.fragment_main, container, false);
categories = (List<JokeCategory>) getArguments().getSerializable("Categories");
// Add the following lines to create RecyclerView
rvcategories = view.findViewById(R.id.rvcategories);
rvcategories.setHasFixedSize(true);
rvcategories.setLayoutManager(new LinearLayoutManager(view.getContext()));
mAdapter = new CategoryListAdapter(categories, getContext(), this);
rvcategories.setAdapter(mAdapter);
return view;
@Override
public void onResume()
categories = (List<JokeCategory>) getArguments().getSerializable("Categories");
rvcategories.getAdapter().notifyDataSetChanged();
super.onResume();
@Override
public void onAttach(@NonNull Context context)
super.onAttach(context);
if (context instanceof onCategoryITemSelected)
listener = (onCategoryITemSelected) context;
else
throw new ClassCastException(context.toString() + "must implement listener");
@Override
public void onListItemClick(JokeCategory item)
Intent i = new Intent(getContext(), ActivityCategory.class);
i.putExtra(ActivityCategory.KEY_EXTRACATEGORY, item);
startActivity(i);
public interface onCategoryITemSelected
void onListItemClick(JokeCategory item);
private List<JokeCategory> DemoData()
List<JokeCategory> data = new LinkedList<>();
data.add(new JokeCategory("Short Jokes"));
data.add(new JokeCategory("Long Jokes"));
data.add(new JokeCategory("One Liner"));
data.add(new JokeCategory("Dumb Jokes"));
data.add(new JokeCategory("Chuck Norris"));
return data;
MainActivity
import androidx.annotation.NonNull;
import androidx.appcompat.app.ActionBarDrawerToggle;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.core.view.GravityCompat;
import androidx.drawerlayout.widget.DrawerLayout;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.MenuItem;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.gms.auth.api.signin.GoogleSignIn;
import com.google.android.gms.auth.api.signin.GoogleSignInAccount;
import com.google.android.gms.auth.api.signin.GoogleSignInClient;
import com.google.android.gms.auth.api.signin.GoogleSignInOptions;
import com.google.android.material.navigation.NavigationView;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener
//global available user data
public static String displayUserName;
public static String displayUserEmail;
GoogleSignInClient mGoogleSignInClient;
private TextView displayName;
private TextView displayEmail;
private DrawerLayout drawerLayout;
private ActionBarDrawerToggle actionBarDrawerToggle;
private Toolbar toolbar;
private NavigationView navigationView;
private FragmentManager fragmentManager;
private FragmentTransaction fragmentTransaction;
private List<JokeCategory> categories;
private Bundle bundle;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
drawerLayout = findViewById(R.id.drawer);
navigationView = findViewById(R.id.navigationView);
navigationView.setNavigationItemSelectedListener(this);
actionBarDrawerToggle = new ActionBarDrawerToggle(this, drawerLayout, toolbar, R.string.open, R.string.close);
drawerLayout.addDrawerListener(actionBarDrawerToggle);
actionBarDrawerToggle.setDrawerIndicatorEnabled(true);
actionBarDrawerToggle.syncState();
categories = DemoData();
bundle = new Bundle();
bundle.putSerializable("Categories", (Serializable) categories);
//load default fragment
fragmentManager = getSupportFragmentManager();
fragmentTransaction = fragmentManager.beginTransaction();
MainFragment mainFragment = new MainFragment();
mainFragment.setArguments(bundle);
fragmentTransaction.replace(R.id.container_fragment, mainFragment);
fragmentTransaction.commit();
// Configure sign-in to request the user's ID, email address, and basic
// profile. ID and basic profile are included in DEFAULT_SIGN_IN.
GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestIdToken(getString(R.string.default_web_client_id))
.requestEmail()
.build();
// Build a GoogleSignInClient with the options specified by gso.
mGoogleSignInClient = GoogleSignIn.getClient(this, gso);
// Side navigation elements (needs headerView since sidenav can be hidden (null)
View headerView = navigationView.getHeaderView(0);
displayName = (TextView) headerView.findViewById(R.id.displayName);
displayEmail = (TextView) headerView.findViewById(R.id.displayEmail);
GoogleSignInAccount account = GoogleSignIn.getLastSignedInAccount(this);
if (account != null)
//account.getDisplayName()
Log.d("AUTH", "User is logged-in automatically");
Toast.makeText(this, "Google Login automatically (already signed in previously)",
Toast.LENGTH_LONG).show();
updateMainActivityUI(account);
else
Log.d("AUTH", "User is NOT logged-in automatically");
public void updateMainActivityUI(GoogleSignInAccount account)
// Global vars
displayUserName = account.getDisplayName();
displayUserEmail = account.getEmail();
//Side nav vars
Log.d("AUTH", "side nav vars: " + displayUserName);
Log.d("AUTH", "side nav vars: " + displayUserEmail);
// if (displayUserName != null)
displayName.setText(displayUserName);
//
// if (displayUserEmail != null)
displayEmail.setText(displayUserEmail);
//
//move to new Fragment
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item)
drawerLayout.closeDrawer(GravityCompat.START);
bundle = new Bundle();
bundle.putSerializable("Categories", (Serializable) categories);
fragmentManager = getSupportFragmentManager();
fragmentTransaction = fragmentManager.beginTransaction();
switch (item.getItemId())
case R.id.home:
MainFragment mainFragment = new MainFragment();
mainFragment.setArguments(bundle);
fragmentTransaction.replace(R.id.container_fragment, mainFragment);
break;
case R.id.newJoke:
NewJokeFragment newJokeFragment = new NewJokeFragment();
newJokeFragment.setArguments(bundle);
fragmentTransaction.replace(R.id.container_fragment, newJokeFragment);
break;
case R.id.logInOut:
fragmentTransaction.replace(R.id.container_fragment, new LogInOutFragment());
break;
case R.id.aboutUs:
fragmentTransaction.replace(R.id.container_fragment, new AboutUsFragment());
break;
case R.id.register:
fragmentTransaction.replace(R.id.container_fragment, new RegisterFragment());
break;
fragmentTransaction.commit();
return true;
private List<JokeCategory> DemoData()
List<JokeCategory> data = new ArrayList<>();
data.add(new JokeCategory("Short Jokes"));
data.add(new JokeCategory("Long Jokes"));
data.add(new JokeCategory("One Liner"));
data.add(new JokeCategory("Dumb Jokes"));
data.add(new JokeCategory("Chuck Norris"));
return data;
public void updateCategories(List<JokeCategory> list)
categories = list;
【问题讨论】:
【参考方案1】:看起来itemView.onClickListener
从未注册过。
将以下行添加到构造函数中。
itemView.setOnClickListener(this);
看起来像:
public CategoryViewHolder(@NonNull View itemView)
super(itemView);
itemView.setOnClickListener(this);
tvCatName = itemView.findViewById(R.id.tvCatName);
tvCatNum = itemView.findViewById(R.id.tvCatNum);
【讨论】:
以上是关于[Android Studio]如何从Fragment中嵌套的Recycleview启动一个Activity?的主要内容,如果未能解决你的问题,请参考以下文章
如何从Mac从android studio中的fabric注销? [复制]
如何向Android Studio里导入从Github上面下载的Project?