问题
I've posted a question regarding of passing data from activity to a fragment. And I've learnt that implementing Parcelable to a POJO class is a right way of doing it. After some research I also understand that in order to pass data to a fragment should use Bundle instead of Intent.
My previous question --> Using same fragments but different content in Android
But now, my question is, what should I do in order to display a list of details (name, address, phone) using set methods when the cardview is clicked?
To be clear, what I want is
- When first restaurant is clicked, the new intent that contains details fragment will be started. Inside the details fragment, it will display the restaurant name, address and phone of the first restaurant.
Can anyone guide me by showing me the code of two set of different details when two different restaurant cardview is clicked?
RestaurantListAdapter.java
I want to use if else statement under onClick, to display different details when different cardview is clicked
public class RestaurantListAdapter extends RecyclerView.Adapter<RestaurantListAdapter.ViewHolder> {
List<RestaurantList_Item> items;
private static ClickListener clickListener;
private Context context;
public RestaurantListAdapter(){
super();
items = new ArrayList<RestaurantList_Item>();
// POSITION 1
RestaurantList_Item restaurant = new RestaurantList_Item();
restaurant.setrImage(R.mipmap.img_anjappar);
restaurant.setrName("Anjappar Indian Chettinad Restaurant");
restaurant.setrCuisine("Indian");
items.add(restaurant);
// POSITION 2
restaurant = new RestaurantList_Item();
restaurant.setrImage(R.mipmap.img_morganfield);
restaurant.setrName("Morganfield");
restaurant.setrCuisine("Western");
items.add(restaurant);
// POSITION 3
restaurant = new RestaurantList_Item();
restaurant.setrImage(R.mipmap.img_nandos);
restaurant.setrName("Nando's");
restaurant.setrCuisine("Western");
items.add(restaurant);
// POSITION 4
restaurant = new RestaurantList_Item();
restaurant.setrImage(R.mipmap.img_shellout);
restaurant.setrName("Shellout");
restaurant.setrCuisine("Seafood");
items.add(restaurant);
// POSITION 5
restaurant = new RestaurantList_Item();
restaurant.setrImage(R.mipmap.img_beyond);
restaurant.setrName("Beyond Veggie");
restaurant.setrCuisine("Vegetarian");
items.add(restaurant);
// POSITION 6
restaurant = new RestaurantList_Item();
restaurant.setrImage(R.mipmap.img_myelephant);
restaurant.setrName("My Elephant");
restaurant.setrCuisine("Thai");
items.add(restaurant);
// POSITION 7
restaurant = new RestaurantList_Item();
restaurant.setrImage(R.mipmap.img_padangkota);
restaurant.setrName("Nasi Kandar Padang Kota");
restaurant.setrCuisine("Mamak");
items.add(restaurant);
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
View v = LayoutInflater.from(viewGroup.getContext())
.inflate(R.layout.cardview_restaurant, viewGroup, false);
ViewHolder viewHolder = new ViewHolder(v);
return viewHolder;
}
@Override
public void onBindViewHolder(final ViewHolder viewHolder, final int position) {
final RestaurantList_Item restaurant = items.get(position);
viewHolder.resImage.setImageResource(restaurant.getrImage());
viewHolder.restaurantName.setText(restaurant.getrName());
viewHolder.cuisine.setText(restaurant.getrCuisine());
viewHolder.itemView.setOnClickListener( new View.OnClickListener() {
@Override
public void onClick(View v) {
Context context = v.getContext();
// Toast.makeText(context, "Item clicked with position " +position, Toast.LENGTH_LONG).show();
if(position == 0){
Intent i = new Intent(context, Restaurant.class);
context.startActivity(i);
}
}
});
}
@Override
public int getItemCount() {
return items.size();
}
@Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
}
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
public ImageView resImage;
public TextView restaurantName;
public TextView cuisine;
public ViewHolder(final View itemView) {
super(itemView);
resImage = (ImageView) itemView.findViewById(R.id.resImage);
restaurantName = (TextView) itemView.findViewById(R.id.restaurantName);
cuisine = (TextView) itemView.findViewById(R.id.cuisine);
itemView.setOnClickListener(this);
}
@Override
public void onClick(View v) {
clickListener.onItemClick(getAdapterPosition(), v);
}
}
public void setOnItemClickListener (ClickListener clickListener){
RestaurantListAdapter.clickListener = clickListener;
}
public interface ClickListener{
void onItemClick (int position, View v);
}
}
RestaurantModel.java
This is the POJO class that contains get set methods, I want to use the set methods to display restaurant details
public class RestaurantModel implements Parcelable{
//empty constructor
public RestaurantModel(){}
//A constructor that initializes the Restaurant object
public RestaurantModel(String resName, String resAddress, String resPhone, String resCuisine, String resPriceRange){
this.resName = resName;
this.resAddress =resAddress;
this.resPhone = resPhone;
this.resCuisine = resCuisine;
this.resPriceRange = resPriceRange;
}
//Parcelling the object
public RestaurantModel(Parcel in){
String[] data = new String [5];
in.readStringArray(data);
this.resName = data[0];
this.resAddress = data[1];
this.resPhone = data[2];
this.resCuisine = data[3];
this.resPriceRange = data[4];
}
// variable main photo
private int mainImage;
//variables for details fragment
private String resName, resAddress, resPhone, resCuisine, resPriceRange;
//variables for menu fragment
private int foodPhoto;
private String foodPrice, foodDescription;
/*get set methods*/
public int getMainImage(){
return mainImage;
}
public void setMainImage(int mainImage){
this.mainImage = mainImage;
}
public String getResName(){
return resName;
}
public void setResName(String resName){
this.resName = resName;
}
public String getResAddress(){return resAddress;}
public void setResAddress(String resAddress){this.resAddress = resAddress;}
public String getResPhone(){return resPhone;}
public void setResPhone(String resPhone){this.resPhone = resPhone;}
public String getResCuisine(){return resCuisine;}
public void setResCuisine(String resCuisine){this.resCuisine = resCuisine;}
public String getResPriceRange(){return resPriceRange;}
public void setResPriceRange(String resPriceRange){this.resPriceRange = resPriceRange;}
public int getFoodPhoto(){return foodPhoto;}
public void setFoodPhoto(int foodPhoto){this.foodPhoto = foodPhoto;}
public String getFoodDescription(){return foodDescription;}
public void setFoodDescription(String foodDescription){this.foodDescription = foodDescription;}
public String getFoodPrice(){return foodPrice;}
public void setFoodPrice(String foodPrice){this.foodPrice = foodPrice;}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeStringArray(new String[]{
this.resName,this.resAddress,this.resPhone, this.resCuisine, this.resPriceRange
});
}
// Creator
public static final Parcelable.Creator<RestaurantModel> CREATOR = new Parcelable.Creator<RestaurantModel>(){
@Override
public RestaurantModel createFromParcel(Parcel source) {
return new RestaurantModel(source);
}
@Override
public RestaurantModel[] newArray(int size) {
return new RestaurantModel[size];
}
};
}
Restaurant.java
This activity contains the fragments that will be shown when the cardview is clicked
public class Restaurant extends AppCompatActivity {
private TabLayout tabLayout;
private ViewPager viewPager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_restaurant);
viewPager = (ViewPager) findViewById(R.id.viewpager);
setupViewPager(viewPager);
tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(viewPager);
}
private void setupViewPager(ViewPager viewPager){
ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
adapter.addFragment(new details(), "Details");
adapter.addFragment(new menu(), "Menu");
adapter.addFragment(new tableBooking(), "Table booking");
viewPager.setAdapter(adapter);
}
class ViewPagerAdapter extends FragmentPagerAdapter{
private final List<Fragment> fragmentList = new ArrayList<>();
private final List<String> fragmentTitleList = new ArrayList<>();
public ViewPagerAdapter(FragmentManager manager){
super(manager);
}
@Override
public Fragment getItem(int position) {
return fragmentList.get(position);
}
@Override
public int getCount() {
return fragmentList.size();
}
public void addFragment (Fragment fragment, String title){
fragmentList.add(fragment);
fragmentTitleList.add(title);
}
@Override
public CharSequence getPageTitle(int position) {
return fragmentTitleList.get(position);
}
}
}
Details.java
This class extends fragment that contains restaurant details such as name, address and phone
public class details extends Fragment {
private TextView resName, resAddress, resPhone, resCuisine, resPriceRange;
public details() {
// Required empty public constructor
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
/* resName = (TextView) getView().findViewById (R.id.resName);
resAddress = (TextView) getView().findViewById (R.id.resAddress);
resPhone = (TextView) getView().findViewById (R.id.resPhone);
resCuisine = (TextView) getView().findViewById (R.id.resCuisine);
resPriceRange = (TextView) getView().findViewById (R.id.resPriceRange);*/
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_details, container, false);
}
}
Homepage.java
public class Homepage extends Activity {
RecyclerView recyclerView;
RecyclerView.LayoutManager llm;
RecyclerView.Adapter adapter;
private static final String TAG = Homepage.class.getSimpleName();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//super.onCreateDrawer(R.layout.activity_homepage);
setContentView(R.layout.activity_homepage);
recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
recyclerView.setHasFixedSize(true);
llm = new LinearLayoutManager(Homepage.this);
recyclerView.setLayoutManager(llm);
adapter = new RestaurantListAdapter();
recyclerView.setAdapter(adapter);
}
}
EDIT: I'm not sure if I'm doing this correctly. I created multiple arraylist that describes different details for different restaurant. I put the code at onClick methods in RestaurantListAdapter.
@Override
public void onBindViewHolder(final ViewHolder viewHolder, final int position) {
final RestaurantList_Item restaurant = items.get(position);
viewHolder.resImage.setImageResource(restaurant.getrImage());
viewHolder.restaurantName.setText(restaurant.getrName());
viewHolder.cuisine.setText(restaurant.getrCuisine());
viewHolder.itemView.setOnClickListener( new View.OnClickListener() {
@Override
public void onClick(View v) {
Context context = v.getContext();
RestaurantModel rAnjappar = new RestaurantModel();
details fragment = new details();
Intent i = new Intent(context, Restaurant.class);
// Array List
ArrayList<RestaurantModel> a1 = new ArrayList<RestaurantModel>();
rAnjappar.setResName("Anjappar");
rAnjappar.setResAddress("Bandar Kinrara");
rAnjappar.setResPhone("03-80807362");
rAnjappar.setResCuisine("Mamak");
rAnjappar.setResPriceRange("RM 30 for 2 person");
ArrayList<RestaurantModel> a2 = new ArrayList<RestaurantModel>();
rAnjappar.setResName("Morganfield");
rAnjappar.setResAddress("Bandar Utama");
rAnjappar.setResPhone("03-80807362");
rAnjappar.setResCuisine("Western");
rAnjappar.setResPriceRange("RM 60 for 2 person");
// action when card view is clicked
if(position == 0){
Bundle b1 = new Bundle();
b1.putParcelableArrayList("anjappar", a1);
fragment.setArguments(b1);
context.startActivity(i);
}
}
});
}
If this is acceptable, next thing I should do is retrieve the bundle in my fragment code right? But since I will be having multiple bundles, how am I supposed to retrieve all the bundles in a correct way?
回答1:
You can use setArguments() method of the fragment to pass your restaurant model class to new fragment while creating the new instance of it.You can get it back using getArguments() in newly created fragment's onCreate()
method. You have to make your resturantModel.java class Serializable.
public class RestaurantModel implements Serializable{
...
}
Add data:-
Bundle bundle = new Bundle();
bundle.putSerializable("restaurant", restaurant);
Fragment1 frag1 = new Fragment1();
frag1.setArguments(bundle);
Get data :-
RestauranModel restaurant = (RestauranModel) getArguments().getSerializable("restaurant");
FYI: Difference between Parcelable and Serializable : https://stackoverflow.com/a/3323554/4690731
回答2:
Ok so from as far as i understand you can do following things
1 Add this method in Adapter
public RestaurantList_Item getItem(int pos) {
return items.get(pos);
}
2. Homepage is your clicklistner activity (Hope so) in it
public void onItemClick(int position, view v) {
RestaurantList_Item row_object = adapter.getItem(position);
Intent i = new Intent(context, Restaurant.class);
i.putExtra(Common.Data_Object, row_object);
startActivity(i);
}
3. Replace code of Restaurant class
public class Restaurant extends AppCompatActivity {
private TabLayout tabLayout;
private ViewPager viewPager;
private RestaurantList_Item row_object;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_restaurant);
getIntentData(getIntent());
viewPager = (ViewPager) findViewById(R.id.viewpager);
setupViewPager(viewPager);
tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(viewPager);
}
private void getIntentData(Intent i) {
if (i != null) {
row_object = i.getParcelableExtra(Common.Data_Object);
}
}
private void setupViewPager(ViewPager viewPager){
ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
Fragment f = new details();
Bundle arguments = new Bundle();
arguments.putParcelable(Common.Data_Object, row_object);
f.setArguments(arguments);
adapter.addFragment(f, "Details");
adapter.addFragment(new menu(), "Menu");
adapter.addFragment(new tableBooking(), "Table booking");
viewPager.setAdapter(adapter);
}
class ViewPagerAdapter extends FragmentPagerAdapter{
private final List<Fragment> fragmentList = new ArrayList<>();
private final List<String> fragmentTitleList = new ArrayList<>();
public ViewPagerAdapter(FragmentManager manager){
super(manager);
}
@Override
public Fragment getItem(int position) {
return fragmentList.get(position);
}
@Override
public int getCount() {
return fragmentList.size();
}
public void addFragment (Fragment fragment, String title){
fragmentList.add(fragment);
fragmentTitleList.add(title);
}
@Override
public CharSequence getPageTitle(int position) {
return fragmentTitleList.get(position);
}
}
}
4. get object from bundle in Detail fragment
private void getIntentData(Bundle b)
{
if (b != null)
{
detailObject = b.getParcelable(Common.Data_Object);
}
}
Hope it will help.
来源:https://stackoverflow.com/questions/36758864/sending-data-from-activity-to-fragment-using-set-methods