I building an app to practice in arraylist and recyclerView.
In the main activity I have "Add" button than I can add things to the arraylit to display in the recyclerView,However,the first time I add new line its working fine,but when I try to add another one,its replacing the first line I added with the new line.
I will be glad if you can point what am I doing wrong,Thank you.
Add Line Activity:
public void AddButton(View view){
if (imageUri != null && !mEditText.getText().toString().isEmpty()){
Intent intent = new Intent(AddCompany.this,MainActivity.class);
intent.putExtra("isAddNewCompany", true);
intent.putExtra("CompanyImage", imageUri.toString());
intent.putExtra("CompanyName", mEditText.getText().toString());
startActivity(intent);
}
}
MainActivity OnCreate with the views:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent intent = getIntent();
ArrayList<String> listTitle = new ArrayList<>();
ArrayList<String> listPicture = new ArrayList<>();
if (intent.getBooleanExtra("isAddNewCompany",false)){
String CompanyImage = intent.getStringExtra("CompanyImage");
String companyName = intent.getStringExtra("CompanyName");
listTitle.add(companyName);
listPicture.add(CompanyImage);
}
// set up the RecyclerView
RecyclerView recyclerView = findViewById(R.id.recyclerView);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
RecyclerAdapter adapter = new RecyclerAdapter(this,listPicture,listTitle);
adapter.setClickListener(new RecyclerAdapter.ItemClickListener() {
#Override
public void onItemClick(View view, int position) {
Log.e("Position Number - ", String.valueOf(position));
Toast.makeText(MainActivity.this, adapter.getItem(position), Toast.LENGTH_SHORT).show();
}
});
recyclerView.setAdapter(adapter);
}
RecyclerView Adapter:
public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.ViewHolder> {
private final ArrayList<String> mData;
private final ArrayList<String> mImageView;
private final LayoutInflater mInflater;
private ItemClickListener mClickListener;
// data is passed into the constructor
RecyclerAdapter(Context context, ArrayList<String> imageView, ArrayList<String> data) {
this.mInflater = LayoutInflater.from(context);
this.mData = data;
this.mImageView = imageView;
}
// inflates the row layout from xml when needed
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = mInflater.inflate(R.layout.recyclerview_row, parent, false);
return new ViewHolder(view);
}
// binds the data to the TextView in each row
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
String animal = mData.get(position);
String picture = mImageView.get(position);
Picasso.get().load(picture).into(holder.myImageView);
holder.myTextView.setText(animal);
}
// total number of rows
#Override
public int getItemCount() {
return mData.size();
}
// stores and recycles views as they are scrolled off screen
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
TextView myTextView;
ImageView myImageView;
ViewHolder(View itemView) {
super(itemView);
myTextView = itemView.findViewById(R.id.tvAnimalName);
myImageView = itemView.findViewById(R.id.imageView);
itemView.setOnClickListener(this);
}
#Override
public void onClick(View view) {
if (mClickListener != null) mClickListener.onItemClick(view, getAdapterPosition());
}
}
// convenience method for getting data at click position
String getItem(int id) {
return mData.get(id);
}
// allows clicks events to be caught
void setClickListener(ItemClickListener itemClickListener) {
this.mClickListener = itemClickListener;
}
// parent activity will implement this method to respond to click events
public interface ItemClickListener {
void onItemClick(View view, int position);
}
}
When you start activity ,every time new list instance will be created that's why you got only one value.if you want already added value, use same list instance.
List<String> listTitle;
List<String> listPicture;
public List<String> getLisPictureInstance(){
if(listPicture ==null)
listPicture = new ArrayList<>();
return listPicture ;
}
public List<String> getListTitleInstance(){
if(listTitle ==null)
listTitle = new ArrayList<>()
return listTitle ;
}
if (intent.getBooleanExtra("isAddNewCompany",false)){
String CompanyImage = intent.getStringExtra("CompanyImage");
String companyName = intent.getStringExtra("CompanyName");
getListTitleInstance().add(companyName);
getLisPictureInstance().add(CompanyImage);
}
Related
I am making a feature for my app where the user can add a new food item inside RecyleView. But instead using a new activity I opted out for a popup that appears in the Main Activity where you can enter the food and the price which means the activity doesn't refresh. How can I display the items in the RecycleView without restarting the app?
Code in Main Activity:
public class SecondScreen extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.second_screen);
myDB = new MyDataBaseHelper(SecondScreen.this);
foodID = new ArrayList<>();
foodName = new ArrayList<>();
foodPrice = new ArrayList<>();
popUp();
//Data from Sql Tables
storeDataInArrays();
customAdapater = new CustomAdapater(SecondScreen.this, foodID, foodName, foodPrice);
recyclerView.setLayoutManager(new LinearLayoutManager(SecondScreen.this));
recyclerView.setAdapter(customAdapater);
//Storing the data from the sql table
public void storeDataInArrays(){
Cursor cursor = myDB.readAllData();
//Gets the count of the rows
if(cursor.getCount() == 0){
Toast.makeText(this, "No data", Toast.LENGTH_SHORT).show();
}else{
while(cursor.moveToNext()){
foodID.add(cursor.getString(0));
foodName.add(cursor.getString(1));
foodPrice.add(cursor.getString(2));
}
}
}
}
public void PopUP(){
btnAddFood.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
MyDataBaseHelper myDB = new MyDataBaseHelper(SecondScreen.this);
myDB.addFood(edtFoodName.getText().toString().trim(),
edtFoodPrice.getText().toString().trim());
//Dismisses the popUp after button click
myDialog.dismiss();
}
});
}
}
Code for RecycleView Adapter
public class CustomAdapater extends RecyclerView.Adapter<CustomAdapater.MyViewHolder> {
Context context;
private ArrayList foodID, foodName, foodPrice;
CheckBox chkItem;
//Constructor
CustomAdapater(Context context, ArrayList foodID, ArrayList foodName, ArrayList foodPrice){
//Declares to global variables that can be used in the MainAcivity
this.context = context;
this.foodID = foodID;
this.foodName = foodName;
this.foodPrice = foodPrice;
}
#NonNull
#Override
public CustomAdapater.MyViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
//Inflates the item_row layout
LayoutInflater inflater = LayoutInflater.from(context);
View view = inflater.inflate(R.layout.item_row, parent, false);
return new MyViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull CustomAdapater.MyViewHolder holder, int position) {
holder.checkItem.setText(String.valueOf(foodName.get(position)));
holder.foodPrice_txt.setText(String.valueOf(foodPrice.get(position) + "$"));
}
#Override
public int getItemCount() {
return foodID.size();
}
public class MyViewHolder extends RecyclerView.ViewHolder {
TextView foodPrice_txt;
CheckBox checkItem;
public MyViewHolder(#NonNull View itemView) {
super(itemView);
checkItem = itemView.findViewById(R.id.chkItemRow);
foodPrice_txt = itemView.findViewById(R.id.txtPriceRow);
}
}
}
Call notifyItemInserted after adding the item to your database and array lists, to update your adapter.
Like so:
String foodName = edtFoodName.getText().toString().trim();
String foodPrice = edtFoodPrice.getText().toString().trim();
myDB.addFood(foodName, foodPrice);
foodNames.add(foodName);
foodPrices.add(foodPrice);
customAdapater.notifyItemInserted(foodNames.size() - 1);
I want to create an onclick listener that reads the String from one TextView and then I somehow pass that string onto the main activity in order to open a third activity
So my main activity looks like this
public class AdvancedResults extends AppCompatActivity {
private RecyclerView mRecyclerView;
private AdvancedAdapter mAdapter;
private RecyclerView.LayoutManager mLayoutManager;
private ArrayList<String> mNames = new ArrayList<>();
private ArrayList<String> mImageUrls = new ArrayList<>();
private ArrayList<String> saved_recipes_with_ingredients = new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_advanced_results);
advancedList.add(new AdvancedItem(R.drawable.ic_android, "test1", "test2");
advancedList.add(new AdvancedItem(R.drawable.ic_android, "test3", "test4");
mRecyclerView = findViewById(R.id.recyclerView1);
mRecyclerView.setHasFixedSize(true);
mLayoutManager = new LinearLayoutManager(this);
mAdapter = new AdvancedAdapter(advancedList);
mRecyclerView.setLayoutManager(mLayoutManager);
mRecyclerView.setAdapter(mAdapter);
mAdapter.setOnItemClickListener(new AdvancedAdapter.OnItemClickListener() {
#Override
public void onItemClick(int position) {
// I want to open a new activity and append the string from the TextView here (maybe with get/set)
}
});
}
And my recycler adapter looks like this
public class AdvancedAdapter extends RecyclerView.Adapter<AdvancedAdapter.AdvancedViewHolder> {
private ArrayList<AdvancedItem> mAdvancedList;
private OnItemClickListener mListener;
public interface OnItemClickListener {
void onItemClick(int position);
}
public void setOnItemClickListener(OnItemClickListener listener) {
mListener = listener;
}
public static class AdvancedViewHolder extends RecyclerView.ViewHolder {
public ImageView mImageView;
public TextView mTextView1;
public TextView mTextView2;
public AdvancedViewHolder(View itemView, final OnItemClickListener listener) {
super(itemView);
mImageView = itemView.findViewById(R.id.imageViewADV);
mTextView1 = itemView.findViewById(R.id.textViewADV1);
mTextView2 = itemView.findViewById(R.id.textViewADV2);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (listener != null) {
int position = getAdapterPosition();
//how do I get the string from the TextView and pass it onto the main class?
if (position != RecyclerView.NO_POSITION) {
listener.onItemClick(position);
}
}
}
});
}
}
public AdvancedAdapter(ArrayList<AdvancedItem> advancedList) {
mAdvancedList = advancedList;
}
#Override
public AdvancedViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.advanced_item, parent, false);
AdvancedViewHolder evh = new AdvancedViewHolder(v, mListener);
return evh;
}
#Override
public void onBindViewHolder(AdvancedViewHolder holder, int position) {
AdvancedItem currentItem = mAdvancedList.get(position);
holder.mImageView.setImageResource(currentItem.getImageResource());
holder.mTextView1.setText(currentItem.getText1());
holder.mTextView2.setText(currentItem.getText2());
}
#Override
public int getItemCount() {
return mAdvancedList.size();
}
i'm just not sure how im supposed to do that and what method to use.
So if you want the text from the text view you do:
String text = textViewId.getText();
But in your case you want to add the text for each one of the views on the list
So on the adapter how make a on click listener:
if (listener != null) {
int position = getAdapterPosition();
String text = mTextView1.getText();
Intent i = new Intent(getApplicationContext(), YourActitivity.class);
i.putExtra("nameYouWant", text)
startActivity(i);
if (position != RecyclerView.NO_POSITION) {
listener.onItemClick(position);
}
Now on your activity :
String text = intent.getStringExtra("nameYouWant");
You can use interface to pass the second String param. So just add one String param like this -
public interface OnItemClickListener {
void onItemClick(int position, String text);
}
And in adapter pass the string on click of the item along with the position
listener.onItemClick(position, mTextView1.getText().toString());
And in the activity, you will receive the String text, from there you can pass it to ThirdActivity via bundle.
mAdapter.setOnItemClickListener(new AdvancedAdapter.OnItemClickListener() {
#Override
public void onItemClick(int position, String textData) {
Intent i = new Intent(this, ThirdActivity.class);
i.putExtra("TEXT_KEY", textData);
}
});
Hope it will help!!
I would like someone to click on an item in my ListView and then my new activity would start and the text of the item they clicked on should be set as the text of the TextView in my new activity. Currently with the following code, my TextView result is:
'com.example.draft.AnimalNames#31571cf'
Here is what I have in MainActivity.java:
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
String clickedName = (list.getItemAtPosition(position).toString());
Intent intent = new Intent(MainActivity.this, Profile.class);
intent.putExtra("clickedName", clickedName);
startActivity(intent);
System.out.println(clickedName);
}
});
And in my new activity:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.profile_layout);
Intent intent = getIntent();
String clickedName = intent.getStringExtra("clickedName");
animalName = findViewById(R.id.textView);
animalName.setText(clickedName);
}
And in my AnimalNames.java file:
public class AnimalNames {
private String animalName;
public AnimalNames(String animalName) {
this.animalName = animalName;
}
public String getanimalName() {
return this.animalName;
}
}
I don't think it's relevant to my question but here is my ListViewAdapter.java file:
public class ListViewAdapter extends BaseAdapter {
// Declare Variables
Context mContext;
LayoutInflater inflater;
private List<AnimalNames> animalNamesList; // Declare a null variable
private ArrayList<AnimalNames> arraylist; // Declare a null array
public ListViewAdapter(Context context, List<AnimalNames> animalNamesList) {
mContext = context;
this.animalNamesList = animalNamesList;
inflater = LayoutInflater.from(mContext);
this.arraylist = new ArrayList<AnimalNames>();
this.arraylist.addAll(animalNamesList);
}
public class ViewHolder {
TextView name;
}
#Override
public int getCount() {
return animalNamesList.size();
}
#Override
public AnimalNames getItem(int position) {
return animalNamesList.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
public View getView(final int position, View view, ViewGroup parent) {
final ViewHolder holder;
if (view == null) {
holder = new ViewHolder();
view = inflater.inflate(R.layout.list_view_items, null); // Locate the TextViews in list_view_items.xml
holder.name = (TextView) view.findViewById(R.id.name);
view.setTag(holder);
} else {
holder = (ViewHolder) view.getTag();
}
// Set the results into TextViews
holder.name.setText(animalNamesList.get(position).getanimalName());
return view;
}
// Filter Class
public void filter(String charText) {
charText = charText.toLowerCase(Locale.getDefault());
animalNamesList.clear();
if (charText.length() == 0) {
animalNamesList.addAll(arraylist);
} else {
for (AnimalNames wp : arraylist) {
if (wp.getanimalName().toLowerCase(Locale.getDefault()).contains(charText)) {
animalNamesList.add(wp);
}
}
}
notifyDataSetChanged();
}
}
String clickedName = (list.getItemAtPosition(position).toString());
By calling toString() method, it will give you the object reference, which is what you get in the TextView.
According to your code, if you wish to see the Animal name, you should do (and fix the method name to getAnimalName):
String clickedName = ((AnimalNames)list.getItemAtPosition(position)).getanimalName();
getItemAtPosition() returns an Object, so you need to cast it to the correct class.
I can't get the layout.xml to show all of the images, it only shows the image that I added into the android:src="blabla.jpg" and all of the list use "blabla.jpg".
I can show the text from the arraylist perfectly fine, but the problem is only the image so i tried this code
public RecyclerViewAdapter(Context mContext,ArrayList<Integer> mImageHolder,ArrayList<String> mItemHolder, ArrayList<String> mDescHolder) {
this.mImageHolder = mImageHolder;
this.mItemHolder = mItemHolder;
this.mDescHolder = mDescHolder;
this.mContext = mContext;
}
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder>{
private static final String TAG = "RecyclerViewAdapter";
private ArrayList<String> mItemHolder = new ArrayList<>();
private ArrayList<String> mDescHolder = new ArrayList<>();
private ArrayList<Integer> mImageHolder = new ArrayList<>();
private Context mContext;
public RecyclerViewAdapter(Context mContext,ArrayList<Integer> mImageHolder,ArrayList<String> mItemHolder, ArrayList<String> mDescHolder) {
this.mImageHolder = mImageHolder;
this.mItemHolder = mItemHolder;
this.mDescHolder = mDescHolder;
this.mContext = mContext;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.layout_list_item, parent, false);
ViewHolder holder = new ViewHolder(view);
return holder;
}
#Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
Log.d(TAG, "onBindViewHolder: called.");
holder.itemHolder.setText(mItemHolder.get(position));
holder.parentLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Log.d(TAG, "onClick: clicked on: " + mItemHolder.get(position));
//ini ke intent
Intent intent = new Intent(mContext, ListDetail.class);
Bundle extras = new Bundle();
extras.putString("EXTRA_ITEM", mItemHolder.get(position));
extras.putString("EXTRA_DESC", mDescHolder.get(position));
extras.putInt("EXTRA_IMAGE", mImageHolder.get(position));
intent.putExtras(extras);
mContext.startActivity(intent);
}
});
}
#Override
public int getItemCount() {
return mItemHolder.size();
}
public class ViewHolder extends RecyclerView.ViewHolder{
TextView itemHolder;
ImageView imageHolder;
RelativeLayout parentLayout;
public ViewHolder(#NonNull View itemView) {
super(itemView);
imageHolder = itemView.findViewById(R.id.ImageItem);
itemHolder = itemView.findViewById(R.id.NameItem);
parentLayout = itemView.findViewById(R.id.parent_layout);
}
}
}
Any help would be appreciated,
In your onBindViewHolder add:
holder.imageHolder.setImageResource(image);
use the setImageresource property of imageView and get the image from the list of that position inside onBindViewHolder.
holder.imageHolder.setImageResource(mImageHolder.get(position));
I have a RecyclerView.Adapter which has some Arrays there.
ArrayList with Strings and ArrayList with Integer. Strings are like url and Integer is the photo.
When the app is open for first time the first item is selected.
I have another method for click which makes another item as selected and this works, but the problem is that the first item stays as selected and so for every image click makes as selected, I want only one item to be selected and take a color.
This is my code.
Adapter of RecyclerView
public class ListViewAdapter extends RecyclerView.Adapter<ListViewAdapter.ViewHolder>{
private int selectedItem;
private ArrayList<Integer> mImages = new ArrayList<>();
private ArrayList<String> mSearchUrl = new ArrayList<>();
private Context mContext;
public ListViewAdapter(ArrayList<Integer> images, ArrayList<String> SearchUrl, Context context) {
mImages = images;
mContext = context;
mSearchUrl = SearchUrl;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.s_engine_item, viewGroup, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull final ViewHolder viewHolder, final int i) {
selectedItem = 0;
if (selectedItem == i) {
viewHolder.image.setBackgroundColor(Color.parseColor("#30000000"));
}
Glide.with(mContext).load(mImages.get(i))
.into(viewHolder.image);
viewHolder.searchUrl.setText(mSearchUrl.get(i));
viewHolder.image.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
viewHolder.image.setBackgroundColor(Color.parseColor("#30000000"));
selectedItem = i;
}
});
}
#Override
public int getItemCount() {
return mImages.size();
}
public class ViewHolder extends RecyclerView.ViewHolder{
ImageView image;
TextView searchUrl;
public ViewHolder(#NonNull View itemView) {
super(itemView);
image = itemView.findViewById(R.id.ivEngine);
searchUrl = itemView.findViewById(R.id.ivEngineText);
}
}
}
And this is the MainActivity.class
public void intSearch() {
mImages.add(R.drawable.s_bing);
mSearchUrl.add("https://www.bing.com/search?q=");
mImages.add(R.drawable.s_google);
mSearchUrl.add("https://www.google.com/search?q=");
mImages.add(R.drawable.s_yahoo);
mSearchUrl.add("www.yahoo.com");
mImages.add(R.drawable.amazon_white256);
mSearchUrl.add("www.amazon.com");
mImages.add(R.drawable.amazon_white256);
mSearchUrl.add("www.amazon.com");
mImages.add(R.drawable.amazon_white256);
mSearchUrl.add("www.amazon.com");
initRecyclerView();
}
private void initRecyclerView() {
LinearLayoutManager layoutManager = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);
RecyclerView recyclerView = findViewById(R.id.lvEngines);
recyclerView.setLayoutManager(layoutManager);
ListViewAdapter adapter = new ListViewAdapter(mImages, mSearchUrl, this);
recyclerView.setAdapter(adapter);
}
Initialize your selected item globally
public class ListViewAdapter extends RecyclerView.Adapter<ListViewAdapter.ViewHolder>{
private int selectedItem = 0;
.....
Then inside your onBindViewHolder whenever you click a new Image notify your adapter for changes in the last selected item cell.
viewHolder.image.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int previousSelectedItem = selectedItem;
selectedItem = i;
notifyItemChanged(previousSelectedItem);
viewHolder.image.setBackgroundColor(Color.parseColor("#30000000"));
}
});
Just remove this line from onBindViewHolder
selectedItem = 0;
and add an else to the background condition, like:
if (selectedItem == i) {
viewHolder.image.setBackgroundColor(Color.parseColor("#30000000"));
}else{
viewHolder.image.setBackgroundColor(“YOUR_DEFAULT_COLOR”);
}
and update the onClick:
viewHolder.image.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
selectedItem = i;
notifyDataSetChanged();
}
});