繁体   English   中英

如何在传递单击的自定义列表项的数据时单击带有RecyclerView的片段项时打开新活动?

[英]How to open a new activity when an item of a fragment with RecyclerView is clicked while passing the data of the clicked custom list item?

我制作了一个自定义的Place对象和Place Adapter。 我使用了Parcelable但是当我点击碎片的任何项目时没有任何反应

尝试使用Parcelable但没有响应点击任何项目。

放置对象

public class Place implements Parcelable {


/** String resource ID for the name of the place */
private int mPlaceID;

private int mImageResourceId;

private int mNearestStation;

private int mSiteInfo;

public Place(int placeID, int imageResourceId, int NearestStation, int 
SiteInfo) {
    mPlaceID = placeID;
    mImageResourceId = imageResourceId;
    mNearestStation = NearestStation;
    mSiteInfo = SiteInfo;
}

protected Place(Parcel in) {
    mImageResourceId = in.readInt();
    mPlaceID = in.readInt ();
    mNearestStation = in.readInt ();
    mSiteInfo = in.readInt ();

}

public static final Creator<Place> CREATOR = new Creator<Place>() {
    @Override
    public Place createFromParcel(Parcel in) {
        return new Place (in);
    }

    @Override
    public Place[] newArray(int size) {
        return new Place[size];
    }
};

/**
 * Get the string resource ID for the name of the place.
 */
public int getPlaceName() {
    return mPlaceID;
}

/**
 * Return the image resource ID of the place.
 */
public int getImageResourceId() {
    return mImageResourceId;
}

public int getNearestStation() {
    return mNearestStation;
}

public int getSiteInfo() {
    return mSiteInfo;
}

@Override
public int describeContents() {
    return 0;
}

@Override
public void writeToParcel(Parcel parcel, int i) {
    parcel.writeInt(mImageResourceId);
    parcel.writeInt(mPlaceID);
    parcel.writeInt ( mNearestStation );
    parcel.writeInt ( mSiteInfo );
}

}

放置适配器

public class PlaceAdapter extends 
RecyclerView.Adapter<PlaceAdapter.PlaceViewHolder> {

Context mContext;
List<Place> mData;

public static class PlaceViewHolder extends RecyclerView.ViewHolder{

    public TextView mTextView;
    public ImageView mImageView;

    public PlaceViewHolder(@NonNull View itemView) {
        super ( itemView );
        mTextView = itemView.findViewById ( R.id.ImageViewText );
        mImageView = itemView.findViewById ( R.id.ImageView );

    }
}

public PlaceAdapter(Context mContext, List<Place> mData){

    this.mContext = mContext;
    this.mData = mData;

}

@NonNull
@Override
public PlaceViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int 
viewType) {
    View v = LayoutInflater.from ( mContext ).inflate ( 
R.layout.list_item, parent, false );
    PlaceViewHolder pvh = new PlaceViewHolder ( v );
    return pvh;
}

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


    holder.mTextView.setText ( mData.get ( position ).getPlaceName () );
    holder.mImageView.setImageResource ( mData.get ( position 
).getImageResourceId () );

}

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

public interface OnPlaceListener{

    void onPlaceClick(int position);
}

}

这是我单击该项目的片段之一

public class MonumentsFragment extends Fragment implements 
PlaceAdapter.OnPlaceListener {

private RecyclerView mRecyclerView;

public MonumentsFragment() {
    // Required empty public constructor
}

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


    final List<Place> places = new ArrayList<> ();

    Place place1 = new Place(R.string.monument1, 
R.drawable.windsor_castle, R.string.monument1S, R.string.monument1I);
    places.add(place1);

    Place place2 = new Place(R.string.monument2, 
R.drawable.trafalgar_square,R.string.monument2S, R.string.monument2I);
    places.add(place2);

    Place place3 = new Place(R.string.monument3, 
R.drawable.buckingham_palace,R.string.monument3S, R.string.monument3I);
    places.add(place3);

    Place place4 = new Place(R.string.monument4, 
R.drawable.bank_of_england,R.string.monument4S, R.string.monument4I);
    places.add(place4);

    Place place5 = new Place(R.string.monument5, 
R.drawable.kensington_palace,R.string.monument5S, R.string.monument5I);
     places.add(place5);

    Place place6 = new Place(R.string.monument6, 
R.drawable.london_wall,R.string.monument6S, R.string.monument6I);
    places.add(place6);


    mRecyclerView = (RecyclerView) rootView.findViewById ( 
R.id.recycler_view );
    PlaceAdapter placeAdapter = new PlaceAdapter ( getContext (), places 
);

    mRecyclerView.setLayoutManager ( new LinearLayoutManager ( getActivity 
() ) );
    mRecyclerView.setAdapter ( placeAdapter );

    return rootView;



}

@Override
public void onPlaceClick(int position) {
    Intent intent = new Intent( MonumentsFragment.this.getActivity () 
,SelectedPlaceActivity.class );
    intent.putExtra("Place Item", position);
    startActivity ( intent );
}


}

这是我想点击时打开的活动

public class SelectedPlaceActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView( R.layout.selected_place);

    Intent intent = getIntent();

    if (intent!=null) {
        Place currentPlace = intent.getParcelableExtra("Place Item");


        int imageRes = currentPlace.getImageResourceId ();

        int placeName = currentPlace.getPlaceName ();

        int nearestStation = currentPlace.getNearestStation ();

        int moreInfo = currentPlace.getSiteInfo ();

        ImageView placeImage = findViewById (R.id.selected_place_image );
        TextView namePlace = findViewById ( R.id.selected_place_name );
        TextView station = findViewById ( R.id.nearest_station );
        TextView information = findViewById ( R.id.more_info );


        placeImage.setImageResource(imageRes);
        namePlace.setText(placeName);
        station.setText(nearestStation);
        information.setText ( moreInfo );
    }

}
}

点击片段中的任何项目都没有响应

您尚未将侦听器分配给项的onClick ,并将侦听器传递给适配器的构造函数。 请按照以下步骤操作。

步骤1PlaceAdapter类中声明侦听器,并通过将其传递给构造函数为其分配值,如下所示。

// declare the listener
OnPlaceListener mListener;

// pass the listener along with Context and the List
public PlaceAdapter(Context mContext, List<Place> mData, OnPlaceListener listener){

    this.mContext = mContext;
    this.mData = mData;
    // assign the listener
    this.mListener = listener;

}

步骤2您需要将侦听器分配给onBindViewHolder方法中onBindViewHolder的onClick

@Override
public void onBindViewHolder(@NonNull PlaceViewHolder holder, int
        position) {
    // assign the listener here
    holder.itemView.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(final View v) {
            mListener.onPlaceClick(position);
        }
    });
    holder.mTextView.setText ( mData.get ( position ).getPlaceName () );
    holder.mImageView.setImageResource ( mData.get ( position
    ).getImageResourceId () );

}

步骤3在片段中将侦听器传递给适配器。

PlaceAdapter placeAdapter = new PlaceAdapter(getContext(), places, this);

另外 ,我注意到你正在将位置传递给意图。 相反,您需要传递与该位置相关的Place对象

@Override
public void onPlaceClick(int position) {
    Intent intent = new Intent( MonumentsFragment.this.getActivity ()
            ,SelectedPlaceActivity.class );
    intent.putExtra("Place Item", places.get(position));
    startActivity ( intent );
}

请注意,您需要声明List onisde onCreateView以从onPlaceClick方法访问它。

public class MonumentsFragment extends Fragment implements
        PlaceAdapter.OnPlaceListener {

    private RecyclerView mRecyclerView;
    // Declare the list here
    private List<Place> places;

    public MonumentsFragment() {
        // Required empty public constructor
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View rootView = inflater.inflate( R.layout.places_list, container,
                false);
        // initialize the list 
        places = new ArrayList<>();

        Place place1 = new Place(R.string.monument1, 
                                 R.drawable.windsor_castle, R.string.monument1S, R.string.monument1I);
        places.add(place1);

        // rest of the code

为了能够单击RecyclerView项目,您需要在项目上提供setOnClickListener 例如,您可以在适配器的onCreateViewHolder中执行此操作。

public ExampleAdapter.ExampleViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
    View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.example_item, viewGroup, false);
    final ExampleViewHolder holder = new ExampleViewHolder(view);

    holder.itemView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            // actions that you need to perform
        }
    });

    return holder;
}

如果您需要获取项目位置,可以使用holder.getAdapterPosition() 如果您需要其他说明,请提供有关所需结果的更多详细信息。

如果你正在使用内部接口,你可以使用listener.onPlaceClick(holder.getAdapterPosition())并覆盖所需的方法来打开新活动或将代码放在适配器中并使用mData.get()来获取你的对象intent 你可以从v获得context

---更新---

为了能够从RecyclerViewAdapter类启动活动,您需要传递上下文。 有两种方法,您可以从View获取它或在构造函数中分配上下文。

 holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
      public void onClick(View v) {
          Intent intent = new Intent (v.getContext(), *needed_activity_class*);
          // put all that you need in intent
          v.getContext().startActivity(intent);
      }
 });

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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