Inserting a TextView text to SQLite upon a Button click - android

Question: How do I pass a TextView information into a variable so when a button is clicked it will add that information to a created SQLite database called collections.
Files left out (because I didn't think they related: androidmanafest.xml, database.java (this was for populating the cards database), and cards.java (for setters getters).
What it looks like:
enter image description here
Main Activity:
public class MainActivity extends AppCompatActivity {
RecyclerView recyclerView;
RecyclerView.LayoutManager layoutManager;
SearchAdapter adapter;
MaterialSearchBar materialSearchBar;
List<String> suggestList = new ArrayList<>();
Database database;
//used for inserting card into collection database
DB_Controller controller;
TextView card_name, type, rarity, artist;
Button addCollectionButton;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//This is all for the controller in order to pass each card into collection database
controller = new DB_Controller(this,"collection.db",null,1);
setContentView(R.layout.layout_item);
card_name = (TextView)findViewById(R.id.card_name);
type = (TextView)findViewById(R.id.type);
rarity = (TextView)findViewById(R.id.rarity);
artist = (TextView)findViewById(R.id.artist);
//functionality of button "ADD TO COLLECTION"
addCollectionButton = (Button)findViewById(R.id.button_collection);
addCollectionButton.setOnClickListener(new View.OnClickListener() {
//when button clicked, insert into collection database
#Override
public void onClick(View view) {
String nameCard = card_name.getText().toString();
String typeCard = type.getText().toString();
String rarityCard = rarity.getText().toString();
String artistCard = artist.getText().toString();
//switch is used in case we need to add more buttons elsewhere in the app
//switch(view.getId()){
// case R.id.button_collection:
//controller.insert_card("drl","drl", "drl", "drl", "drl");
Toast.makeText(getBaseContext(), "ADDED TO COLLECTION", Toast.LENGTH_LONG).show(); //confirm card was added
//break;
//}
}
});
setContentView(R.layout.activity_main);
//init View
recyclerView = (RecyclerView)findViewById(R.id.recycler_search);
layoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setHasFixedSize(true);
materialSearchBar = (MaterialSearchBar)findViewById(R.id.search_bar);
//materialSearchBar.inflateMenu(R.layout.activity_main);
//init DB
database = new Database(this);
//setup search bar
//materialSearchBar.setHint("Search");
//materialSearchBar.setCardViewElevation(10);
loadSuggestList();
//This is used when typing in search bar suggesting words like those that have been typed
materialSearchBar.addTextChangeListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence charSequence, int start, int count, int after) {
}
// method for when user types in search bar, return suggested strings
#Override
public void onTextChanged(CharSequence charSequence, int start, int before, int after) {
List<String> suggest = new ArrayList<>();
for(String search : suggestList) {
if(search.toLowerCase().contains(materialSearchBar.getText().toLowerCase()))
suggest.add(search);
}
materialSearchBar.setLastSuggestions(suggest);
}
#Override
public void afterTextChanged(Editable editable) {
}
});
//This is used when user has typed the word(s) needed to search and hits the search icon
materialSearchBar.setOnSearchActionListener(new MaterialSearchBar.OnSearchActionListener() {
#Override
public void onSearchStateChanged(boolean enabled) {
if(!enabled)
recyclerView.setAdapter(adapter);
}
#Override
public void onSearchConfirmed(CharSequence text) {
startSearch(text.toString());
}
#Override
public void onButtonClicked(int buttonCode) {
}
});
//init Adapter default set all result
//adapter = new SearchAdapter(this, database.getFriends());
adapter = new SearchAdapter(this, database.getCards());
recyclerView.setAdapter(adapter);
}
private void startSearch(String text) {
//adapter = new SearchAdapter(this, database.getFriendByName(text));
adapter = new SearchAdapter(this, database.getCardsByName(text));
recyclerView.setAdapter(adapter);
}
//for populating suggestion list when search bar has been activated
private void loadSuggestList() {
suggestList = database.getNames();
materialSearchBar.setLastSuggestions(suggestList);
}
}
layout_item.xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardElevation="8dp"
android:layout_margin="8dp">
<!--Creation of overall look of searched results
Main design tile for each searched result-->
<LinearLayout
android:orientation="horizontal"
android:layout_margin="8dp"
android:background="#android:color/white"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<!--default image for each tile-->
<ImageView
android:src="#drawable/ic_image_black_24dp"
android:layout_width="70dp"
android:layout_height="70dp" />
<!--design tile within the main tile to display the information pulled from database-->
<LinearLayout
android:orientation="vertical"
android:layout_weight="9"
android:layout_width="0dp"
android:layout_height="wrap_content">
<!--information pulled from database design: NAME
android:id="#+id/name"-->
<TextView
android:id="#+id/card_name"
android:layout_marginLeft="10dp"
android:gravity="center_vertical|start"
android:textAllCaps="true"
android:textStyle="bold"
android:text="Eddy Lee"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<!--information pulled from database design: EMAIL
android:id="#+id/email"-->
<TextView
android:id="#+id/type"
android:layout_marginLeft="10dp"
android:gravity="center_vertical|start"
android:textStyle="italic"
android:text="eddy#gmail.com"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<!--information pulled from database design: PHONE
android:id="#+id/phone"-->
<TextView
android:id="#+id/rarity"
android:layout_marginLeft="10dp"
android:gravity="center_vertical|start"
android:textAllCaps="true"
android:textStyle="bold"
android:text="(123)456-7890"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<!--information pulled from database design: ADDRESS
android:id="#+id/address"-->
<TextView
android:id="#+id/artist"
android:layout_marginLeft="10dp"
android:gravity="center_vertical|start"
android:textAllCaps="true"
android:textStyle="normal"
android:text="123 Seseme Street"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button
android:id="#+id/button_collection"
android:layout_width="200dp"
android:layout_height="35dp"
android:text="Add to Collection"
/>
</LinearLayout>
</LinearLayout>
</android.support.v7.widget.CardView>
activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.darrelbott.search.MainActivity">
<com.mancj.materialsearchbar.MaterialSearchBar
app:mt_speechMode="false"
app:mt_hint="Custom hint"
app:mt_maxSuggestionsCount="10"
app:mt_searchBarColor="#color/colorPrimary"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/search_bar" />
<android.support.v7.widget.RecyclerView
android:id="#+id/recycler_search"
android:layout_below="#+id/search_bar"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</RelativeLayout>
DB_Controller:
public class DB_Controller extends SQLiteOpenHelper {
private static final String TABLE_COLLECTION = "collection";
private static final String COLUMN_COLLECTION_ACCOUNT = "account";
private static final String COLUMN_COLLECTION_NAME = "card_name";
private static final String COLUMN_COLLECTION_TYPE = "type";
private static final String COLUMN_COLLECTION_RARITY = "rarity";
private static final String COLUMN_COLLECTION_ARTIST = "artist";
SQLiteDatabase db;
Context context;
int version = 1;
public DB_Controller(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
super(context, "collection.db", factory, version);
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE " + TABLE_COLLECTION + " (id INTEGER PRIMARY KEY AUTOINCREMENT, "
+ COLUMN_COLLECTION_ACCOUNT + " TEXT, "
+ COLUMN_COLLECTION_NAME + " TEXT, "
+ COLUMN_COLLECTION_TYPE + " TEXT, "
+ COLUMN_COLLECTION_RARITY + " TEXT, "
+ COLUMN_COLLECTION_ARTIST + " TEXT)");
}
#Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
//sqLiteDatabase.execSQL("DROP TABLE IF EXISTS collection;");
//onCreate(sqLiteDatabase);
}
public void insert_card(String account, String card_name, String type, String rarity, String artist) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put(COLUMN_COLLECTION_ACCOUNT,account);
contentValues.put(COLUMN_COLLECTION_NAME,card_name);
contentValues.put(COLUMN_COLLECTION_TYPE,type);
contentValues.put(COLUMN_COLLECTION_RARITY,rarity);
contentValues.put(COLUMN_COLLECTION_ARTIST,artist);
db.insert(TABLE_COLLECTION,null,contentValues);
//this.getWritableDatabase().insertOrThrow("collection.db","",contentValues);
}
}
Adapter (which holds both SearchAdapter & SearchViewHolder):
class SearchViewHolder extends RecyclerView.ViewHolder {
//public TextView name, address, email, phone;
public TextView card_name, type, rarity, artist;
public SearchViewHolder(#NonNull View itemView) {
super(itemView);
card_name = (TextView)itemView.findViewById(R.id.card_name);
type = (TextView)itemView.findViewById(R.id.type);
rarity = (TextView)itemView.findViewById(R.id.rarity);
artist = (TextView)itemView.findViewById(R.id.artist);
}
}
public class SearchAdapter extends RecyclerView.Adapter<SearchViewHolder> {
private Context context;
//private List<Friend> friends;
private List<Cards> cards;
public SearchAdapter(Context context, List<Cards> cards /*List<Friend> friends*/ ) {
this.context = context;
//this.friends = friends;
this.cards = cards;
}
#NonNull
#Override
public SearchViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
View itemView = inflater.inflate(R.layout.layout_item, parent, false);
return new SearchViewHolder(itemView);
}
Button addCollectionButton;
#Override
public void onBindViewHolder(#NonNull SearchViewHolder holder, int position) {
/*
holder.name.setText(friends.get(position).getName());
holder.address.setText(friends.get(position).getAddress());
holder.email.setText(friends.get(position).getEmail());
holder.phone.setText(friends.get(position).getPhone());
*/
holder.card_name.setText(cards.get(position).getName());
holder.type.setText(cards.get(position).getType());
holder.rarity.setText(cards.get(position).getRarity());
holder.artist.setText(cards.get(position).getArtist());
/*
//functionality of button "ADD TO COLLECTION"
final DB_Controller controller = new DB_Controller(this,"collection.db",null,1);
addCollectionButton.setOnClickListener(new View.OnClickListener() {
//when button clicked, insert into collection database
#Override
public void onClick(View view) {
//String card_name1 = card_name.setText(cards.get(position).getName());
//switch is used in case we need to add more buttons elsewhere in the app
//switch(view.getId()){
// case R.id.button_collection:
controller.insert_card("drl","drl", "drl", "drl", "drl");
//Toast.makeText(getApplicationContext(), "ADDED TO COLLECTION", Toast.LENGTH_LONG).show(); //confirm card was added
//break;
//}
}
});
*/
}
#Override
public int getItemCount() {
//return friends.size();
return cards.size();
}
}

You need to have the onClickListener inside the adapter where the button actually is. What you have done is have the listener in the main activity which is not correct. Put your listener in onBindViewHolder() and it should work if there is no issue in the sql code

As I commented earlier: You need to add the onClick() method of your "addCollectionButton" Button to your custom adapter class in the onBindViewHolder() method. The "button_collection" Button in your CardView layout has nothing to do with the "main_activity" layout.
Try this code for your Adapter.
Note: I did this in a text editor, so there might be a couple of typos!
Also Note: I changed you "cards" List into an ArrayList--so you will need to compensate in you Activity code.
public class SearchAdapter extends RecyclerView.Adapter<SearchAdapter.MyViewHolder> {
private static final String TAG = SearchAdapter.class.getSimpleName();
private Context mContext;
private final DB_Controller dbController;
private ArrayList<Cards> cards;
public class MyViewHolder extends RecyclerView.ViewHolder {
public TextView card_name, type, rarity, artist;
public Button addCollectionButton;
public MyViewHolder(View itemView) {
super(itemView);
card_name = (TextView)itemView.findViewById(R.id.card_name);
type = (TextView)itemView.findViewById(R.id.type);
rarity = (TextView)itemView.findViewById(R.id.rarity);
artist = (TextView)itemView.findViewById(R.id.artist);
addCollectionButton = (Button)itemView.findViewById(R.id.button_collection);
}
}
public SearchAdapter(Context context, ArrayList<Cards> cards) {
this.mContext = context;
dbController = new DB_Controller(context,"collection.db",null,1);
this.cards = cards;
}
#Override
public MyViewHolder onCreateViewHolder(final ViewGroup parent, final int viewType) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
View itemView = inflater.inflate(R.layout.layout_item, parent, false);
return new MyViewHolder(itemView);
}
#Override
public void onBindViewHolder(MyViewHolder holder, int position) {
Cards cardsData = cards.get(position);
holder.card_name.setText(cardsData.getName());
holder.type.setText(cardsData.getType());
holder.rarity.setText(cardsData.getRarity());
holder.artist.setText(cardsData.getArtist());
holder.addCollectionButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Log.e(TAG, "on click " + position);
String cardName = cardsData.getName();
String cardType = cardsData.getType();
String cardRarity = cardsData.getRarity();
String cardArtist = cardsData.getArtist();
// You will need to add the data as needed!
dbController.insert_card("drl","drl", "drl", "drl", "drl");
Toast.makeText(mContext, "ADDED TO COLLECTION: " + cardName, Toast.LENGTH_LONG).show(); //confirm card was added
}
});
}
#Override
public int getItemCount() {
return cards.size();
}
}
----------
Please let me know if you have any issues with the above code.

Related

RecyclerView shows Strings but not Images

I have a SQLite database and want to search Items thorugh DB and then showing the items on recyclerView. Everything looking fine but recyclerView not showing the pictures, But somehow It shows the Strings
Normally pictures I saved inside the SQLite as BLOB should be displayed on the left.
Here is SearchFragment (Where I make the search and start recyclerView to display items)
public class SearchFragment extends Fragment {
Button searchbutton;
EditText editText;
View v;
Cursor cursor;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
v = inflater.inflate(R.layout.fragment_search, container, false);
addListenerOnButton(v);
return v;
}
private void addListenerOnButton(View v) {
searchbutton = v.findViewById(R.id.searchfragment_button);
editText = v.findViewById(R.id.searchfragment_edittext);
searchbutton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String keystring = editText.getText().toString();
if(keystring.isEmpty())
Toast.makeText(getContext(),R.string.empty_search ,Toast.LENGTH_LONG).show();
else
new FoodQuery().execute(keystring);
}
});
}
//Place I start the search on background
private class FoodQuery extends AsyncTask<String, Void, Void>{
#Override
protected Void doInBackground(String [] keys) {
String name_col;
DietAppDatabaseHelper daDBHelper;
SQLiteDatabase daDB;
daDBHelper = new DietAppDatabaseHelper(getContext());
try {
daDB = daDBHelper.getReadableDatabase();
if (Locale.getDefault().getLanguage() == "tr")
name_col = "name_tr";
else
name_col = "name_eng";
String query = "SELECT * FROM food_data WHERE " //Query here
+ name_col + " LIKE ?" ;
cursor = daDB.rawQuery(query, new String[]{"%" + keys[0] + "%"});
viewResults(name_col);
daDB.close();
} catch (SQLiteException e){
Log.d("SearchFragment", "doInBackground: " + e);
}
return null;
}
}
private void viewResults(String lang) {
int name_col = -1; //For language issues not important
if(lang == "name_tr")
name_col = 1;
else if(lang == "name_eng")
name_col = 2;
ArrayList<String> tmpnames = new ArrayList<>(); //I put pictures to byte[] and names to String Arraylist here
ArrayList<byte[]> tmppictures = new ArrayList<>();
if(cursor.moveToFirst()){
tmpnames.add(cursor.getString(name_col));
tmppictures.add(cursor.getBlob(5));
while(cursor.moveToNext()){
tmpnames.add(cursor.getString(name_col));
tmppictures.add(cursor.getBlob(5));
}
}
else {
Looper.prepare();
Toast.makeText(getContext(), R.string.no_food_found, Toast.LENGTH_LONG).show(); //To prevent empty search
}
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
RecyclerView recyclerView = v.findViewById(R.id.recycler_view);
SearchResultAdapter adapter = new SearchResultAdapter(getContext(), tmppictures, tmpnames);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false));
recyclerView.setAdapter(adapter);
}
});
}
}
Layout File of SearchFragment
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context=".fragments.SearchFragment"
android:id="#+id/fragment_search">
<Button
android:id="#+id/searchfragment_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="60dp"
android:layout_marginEnd="4dp"
android:layout_marginRight="4dp"
android:text="#string/nav_search"
android:textColor="#FFFFFF"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<EditText
android:id="#+id/searchfragment_edittext"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginLeft="16dp"
android:layout_marginTop="64dp"
android:ems="10"
android:inputType="textPersonName"
app:layout_constraintEnd_toStartOf="#+id/searchfragment_button"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="124dp"
app:layout_constraintTop_toTopOf="parent"
tools:layout_editor_absoluteX="0dp">
</androidx.recyclerview.widget.RecyclerView>
</androidx.constraintlayout.widget.ConstraintLayout>
Here is the adapter
public class SearchResultAdapter extends RecyclerView.Adapter<SearchResultAdapter.ViewHolder>{
private ArrayList<byte[]> foodimages;
private ArrayList<String> foodnames;
private Context context;
public SearchResultAdapter(Context context, ArrayList<byte[]> foodimages, ArrayList<String> foodnames) {
this.foodimages = new ArrayList<>(foodimages);
this.foodnames = new ArrayList<>(foodnames);
this.context = context;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.search_result_item, parent, false);
ViewHolder holder = new ViewHolder(view);
return holder;
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
holder.foodname.setText(foodnames.get(position));
holder.foodimage.setImageBitmap(BitmapFactory.decodeByteArray(foodimages.get(position), 0, foodimages.size()));
}
#Override
public int getItemCount() {
return foodnames.size();
}
public class ViewHolder extends RecyclerView.ViewHolder{
ImageView foodimage;
TextView foodname;
RelativeLayout parentLayout;
public ViewHolder(#NonNull View itemView) {
super(itemView);
foodimage = itemView.findViewById(R.id.food_seacrh_image);
foodname = itemView.findViewById(R.id.food_search_name);
parentLayout = itemView.findViewById(R.id.search_item);
}
}
}
Lastly, the layout of my item to use in recyclerView
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="15dp"
android:id="#+id/search_item">
<ImageView
android:id="#+id/food_seacrh_image"
android:layout_width="100dp"
android:layout_height="100dp"
/>
<TextView
android:id="#+id/food_search_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#+id/food_seacrh_image"
android:textColor="#FFFFFF"
android:layout_centerVertical="true"
android:layout_marginLeft="30dp"
android:textSize="17sp"
android:layout_toEndOf="#+id/food_seacrh_image"
android:layout_marginStart="30dp" />
It seems like the problem could be the line:
holder.foodimage.setImageBitmap(BitmapFactory.decodeByteArray(foodimages.get(position), 0, foodimages.size()));
Should probably be:
holder.foodimage.setImageBitmap(BitmapFactory.decodeByteArray(foodimages.get(position), 0, foodimages.get(position).size));
The third param on decodeByteArray should be the length (in bytes) of the image, you are passing in the actual number of images.

Displaying data in a RecyclerView

I have this working perfectly with a ListView, but decided to update my code to use RecyclerView.
I see there is no default implementation, and the responses to similar questions are quite old.
Is using a sort of cursor the best way to go, or is there a better option?
These are my code snippets for a working RecyclerView with hard-coded values:
MainActivity
recyclerView = (RecyclerView)findViewById(R.id.recycler_view);
mLayoutmanager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(mLayoutmanager);
mAdapter = new recyclerViewDataAdapter();
recyclerView.setAdapter(mAdapter);
recyclerViewDataAdapter
public class recyclerViewDataAdapter extends RecyclerView.Adapter {
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
//lets populate our recyler view with the item created;
//get the view from the layout inflator
// third parameter is set to false to prevent viewgroup to attach to root
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_item,parent,false);
// as this method need to return the viewHolder type
// need to convert our view to the view holder
RecyclerView.ViewHolder viewHolder = new RecyclerView.ViewHolder(view) {
#Override
public String toString() {
return super.toString();
}
};
return viewHolder;
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
}
#Override
public int getItemCount() {
return 3000;
}
}
activity_main
<android.support.v7.widget.RecyclerView
android:id="#+id/recycler_view"
android:scrollbars="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
recycler_item
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:orientation="vertical">
<TextView
android:id="#+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Hii "
android:textSize="30sp" />
</LinearLayout>
Here is my DatabaseAdapter which worked perfectly with a ListView:
public class DatabaseHelper extends SQLiteAssetHelper {
private static final int DATABASE_VERSION = 1;
private static final String DATABASE_NAME = "database9.db";
private static final String BOOKS = "books";
private static final String AUTHORS = "authors";
public DatabaseHelper (Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
// setForcedUpgrade();
}
// Getting all books
public ArrayList<Author> getAllAuthors() {
ArrayList<Author> authorList = new ArrayList<>();
// Select all query
String selectQuery = "SELECT id, name FROM " + AUTHORS + " ORDER BY name_alphabetic";
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
// looping through all rows and adding to list
if (cursor.moveToFirst()) {
do {
// create new author object
Author author = new Author();
// set ID and name of author object
author.setID(Integer.parseInt(cursor.getString(0)));
author.setName(cursor.getString(1));
// pass author object to authorList array
authorList.add(author);
} while (cursor.moveToNext());
}
// return author list
return authorList;
}
}
Your can try
In your activity
ArrayList<Author> authors = dbHandler. getAllAuthors();
recyclerView.setHasFixedSize(true);
// ListView
recyclerView.setLayoutManager(new LinearLayoutManager(youractivity.this));
// create an Object for Adapter
CardViewDataAdapter1 mAdapter = new CardViewDataAdapter1(authors);
// set the adapter object to the Recyclerview
recyclerView.setAdapter(mAdapter);
Your adapter is look like
class CardViewDataAdapter1 extends RecyclerView.Adapter<CardViewDataAdapter1.ViewHolder> {
private ArrayList<Author> dataSet;
public CardViewDataAdapter1(ArrayList<Author> os_versions) {
dataSet = os_versions;
}
#Override
public CardViewDataAdapter1.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
// create a new view
View itemLayoutView = LayoutInflater.from(viewGroup.getContext()).inflate(
R.layout.recycler_item, null);
itemLayoutView.setLayoutParams(new RecyclerView.LayoutParams(RecyclerView.LayoutParams.MATCH_PARENT, RecyclerView.LayoutParams.WRAP_CONTENT));
// create ViewHolder
CardViewDataAdapter1.ViewHolder viewHolder = new CardViewDataAdapter1.ViewHolder(itemLayoutView);
return viewHolder;
}
#Override
public void onBindViewHolder(CardViewDataAdapter1.ViewHolder viewHolder, int i) {
Author fp = dataSet.get(i);
viewHolder.tv_name.setText(fp.getName());
viewHolder.menu = fp;
}
#Override
public int getItemCount() {
return dataSet.size();
}
public void updateList(List<Author> temp) {
dataSet = (ArrayList<Author>) temp;
notifyDataSetChanged();
}
// inner class to hold a reference to each item of RecyclerView
public class ViewHolder extends RecyclerView.ViewHolder {
public TextView tv_name;
public Author menu;
public ViewHolder(View itemLayoutView) {
super(itemLayoutView);
tv_name = (TextView) itemLayoutView .findViewById(R.id.tv_name);
}
}
}
Your recycler_item.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
card_view:cardCornerRadius="5dp"
card_view:cardBackgroundColor="#FFFFFF"
card_view:cardUseCompatPadding="true"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="#+id/tv_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Enamul"/>
</LinearLayout>
</android.support.v7.widget.CardView>

Can't get ImageView to show up on RecyclerView

I am just learning the RecyclerView and cannot figure out why the imageView with android:id="#+id/im_item_icon" will not show up on the screen. I even have another imageView that works but when I swap the IDs the original not working view works and the working one will not work. So basically the problem must be with the ID but I cannot figure out why. BTW I got the code from a blog "http://wiseassblog.com/tutorials/2016/03/04/how-to-build-a-recyclerview/"
DerpAdapter.java
public class DerpAdapter extends RecyclerView.Adapter<DerpAdapter.DerpHolder> {
private List<ListItem> listData;
private LayoutInflater inflater;
public DerpAdapter(List<ListItem> listData, Context c){
inflater = LayoutInflater.from(c);
this.listData = listData;
}
#Override
public DerpAdapter.DerpHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = inflater.inflate(R.layout.list_item, parent, false);
return new DerpHolder(view);
}
#Override
public void onBindViewHolder(DerpHolder holder, int position) {
ListItem item = listData.get(position);
holder.title.setText(item.getTitle());
holder.icon.setImageResource(item.getImageResId());
}
#Override
public int getItemCount() {
return listData.size();
}
class DerpHolder extends RecyclerView.ViewHolder {
private TextView title;
private ImageView icon;
private View container;
public DerpHolder(View itemView) {
super(itemView);
title = (TextView)itemView.findViewById(R.id.lbl_item_text);
icon = (ImageView)itemView.findViewById(R.id.im_item_icon);
//We'll need the container later on, when we add an View.OnClickListener
container = itemView.findViewById(R.id.cont_item_root);
}
}
DerpData.java
public class DerpData {
private static final String[] titles = {"Nothingness cannot be defined",
"Time is like a river made up of the events which happen, and a violent stream; " +
"for as soon as a thing has been seen, it is carried away, and another comes" +
" in its place, and this will be carried away too,",
"But when I know that the glass is already broken, every minute with it is precious.",
"For me, it is far better to grasp the Universe as it really is than to persist in" +
" delusion, however satisfying and reassuring.",
"The seeker after the truth is not one who studies the writings of the ancients and," +
" following his natural disposition, puts his trust in them, but rather the" +
" one who suspects his faith in them and questions what he gathers from them," +
" the one who submits to argument and demonstration, and not to the " +
"sayings of a human being whose nature is fraught with all kinds " +
"of imperfection and deficiency.",
"You must take personal responsibility. You cannot change the circumstances, the" +
" seasons, or the wind, but you can change yourself. That is something you" +
" have charge of."
};
private static final String[] subTitles = {"Bruce Lee",
"Marcus Aurelius",
"Meng Tzu",
"Ajahn Chah",
"Carl Sagan",
"Alhazen",
"Jim Rohn"
};
private static final int icon = R.drawable.ic_tonality_black_36dp;
public static List <ListItem> getListData() {
List <ListItem> data = new ArrayList <>();
//Repeat process 4 times, so that we have enough data to demonstrate a scrollable
//RecyclerView
for (int x = 0; x < 4; x++) {
//create ListItem with dummy data, then add them to our List
for (int i = 0; i < titles.length; i++) {
ListItem item = new ListItem();
item.setTitle(titles[i]);
item.setSubTitle(subTitles[i]);
data.add(item);
}
}
return data;
}
ListItem.java
public class ListItem {
private int imageResId;
private String subTitle;
private String title;
private boolean favourite = false;
public String getSubTitle() {
return subTitle;
}
public void setSubTitle(String subTitle) {
this.subTitle = subTitle;
}
public boolean isFavourite() {
return favourite;
}
public void setFavourite(boolean favourite) {
this.favourite = favourite;
}
public int getImageResId() {
return imageResId;
}
public void setImageResId(int imageResId) {
this.imageResId = imageResId;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
DetailActivity.java
public class DetailActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_detail);
}
ListActivity.java
public class ListActivity extends AppCompatActivity {
private RecyclerView recView;
private DerpAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list);
recView = (RecyclerView)findViewById(R.id.rec_list);
//Check out GridLayoutManager and StaggeredGridLayoutManager for more options
recView.setLayoutManager(new LinearLayoutManager(this));
adapter = new DerpAdapter(DerpData.getListData(), this);
recView.setAdapter(adapter);
}
activity_detail.xml
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="16dp"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:paddingTop="16dp"
tools:context="application.binarysoup.jsonpractice.ui.DetailActivity">
<TextView
android:id="#+id/lbl_quote_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="sans-serif-medium" />
<TextView
android:id="#+id/lbl_quote_attribution"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/lbl_quote_text"
android:fontFamily="sans-serif-light"
android:textStyle="italic" />
activity_list.xml
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="application.binarysoup.jsonpractice.ui.ListActivity"
tools:layout_editor_absoluteX="0dp"
tools:layout_editor_absoluteY="81dp">
<android.support.v7.widget.RecyclerView
android:id="#+id/rec_list"
android:layout_width="match_parent"
android:layout_height="match_parent" />
list_item.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/cont_item_root"
android:layout_width="match_parent"
android:layout_height="72dp"
android:background="#drawable/background_state_drawable"
android:clickable="true"
>
<ImageView
android:id="#+id/im_item_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:paddingLeft="16dp"
android:src="#drawable/ic_tonality_black_36dp" />
<TextView
android:id="#+id/lbl_item_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignTop="#+id/im_item_icon"
android:layout_marginLeft="72dp"
android:layout_marginRight="48dp"
android:ellipsize="end"
android:fontFamily="sans-serif"
android:singleLine="true"
android:text="Sois comme l'eau mon ami"
android:textColor="#android:color/black"
android:textSize="16sp" />
<TextView
android:id="#+id/lbl_item_sub_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/lbl_item_text"
android:layout_marginLeft="72dp"
android:layout_marginRight="48dp"
android:ellipsize="end"
android:fontFamily="sans-serif"
android:singleLine="true"
android:text="Mononc' J"
android:textSize="14sp" />
<ImageView
android:id="#+id/im_item_icon_secondary"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:clickable="true"
android:padding="16dp"
android:src="#drawable/ic_star_border_black_24dp"
android:background="#drawable/background_state_drawable"
/>
Can't get ImageView to show up on RecyclerView
You have to initialize imageResId in order to appear it in the recyclerView
for (int i = 0; i < titles.length; i++) {
ListItem item = new ListItem();
item.setTitle(titles[i]);
item.setSubTitle(subTitles[i]);
//put the code to initialise the imageResId here
data.add(item);
}

ReclyclerView and CardView, onclick method perform the action on several CardViews at same time

I've got a RecyclerView which populates from an ArrayList. The output is a CardView layout.
In the Cardview, there are 2 buttons amongst other Views.
They only have to read the current value of a TextView, which by default is 1, and increase or decrease it.
The Arraylist contains 8 items.
When I run the app the UI works fine. Trouble is when I try to modify the value of the TextView.
The value is correctly increased and decreased on the CardView I'm working on, but ALSO the value is modified on another CardView. And in that second CardView, modifying its TextView value, also modifies the first one.
So, what am I doing wrong?
This is my Fragment:
public class Fragment_rosas extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater,ViewGroup container,Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.layout_rosas,container,false);
RecyclerView recyclerview_rosas;
RecyclerView.Adapter adaptador_rv_rosas;
RecyclerView.LayoutManager lm_rosas;
List rosas = new ArrayList();
rosas.add(new Tropa(1,R.drawable.minibarbaro, getResources().getString(R.string.barbaro),7,1));
recyclerview_rosas = (RecyclerView) view.findViewById(R.id.recyclerView_tropasRosas);
recyclerview_rosas.setHasFixedSize(true);
lm_rosas = new LinearLayoutManager(getContext());
recyclerview_rosas.setLayoutManager(lm_rosas);
adaptador_rv_rosas = new AdaptadorTropa(rosas);
recyclerview_rosas.setAdapter(adaptador_rv_rosas);
return view;
}
}
And here the part of code on my Adapter:
#Override
public void onBindViewHolder(final TropaViewHolder viewHolder, int i) {
viewHolder.imagen.setImageResource(items.get(i).getImagen());
viewHolder.nombre.setText(items.get(i).getNombre());
viewHolder.maxnivel.setText(String.valueOf(items.get(i).getNivelMax()));
viewHolder.espacioencamp.setText((String.valueOf(items.get(i).getEspacioEnCamp())));
final String nombre = items.get(i).getNombre();
final int maxnivel = items.get(i).getNivelMax();
viewHolder.nivelmas.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String niveltemp = viewHolder.nivel.getText().toString();
String nivelmaxtemp = viewHolder.maxnivel.getText().toString();
int nivel = Integer.parseInt(niveltemp);
int maxxnivel = Integer.parseInt(nivelmaxtemp);
int nuevonivel = nivel+1 ;
if (nuevonivel<=maxxnivel) {
viewHolder.txtv_nivel.setText(String.valueOf(nuevonivel));
}
}
});
My OnCreateViewHolder (nothing really happens here):
#Override
public TropaViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View v = LayoutInflater.from(viewGroup.getContext())
.inflate(R.layout.cardview, viewGroup, false);
return new TropaViewHolder(v);
}
Here is the solution, as mentioned in the comment above, it addresses two problems:
1. positiontoValueMap - saves current value for each position
2. onclicklistener is passed to the ViewHolder in onCreateViewHolder
Adapter Class
public class MyAdapter extends RecyclerView.Adapter {
private Context context;
private List<String> dataList;
private Map<Integer, Integer> positionToValueMap = new HashMap<>();
public MyAdapter(Context context, List<String> dataList) {
this.context = context;
this.dataList = dataList;
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.recycler_view_item, null, false);
return new MyViewHolder(view, new OnRecyclerItemClickListener());
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
((MyViewHolder) holder).onRecyclerItemClickListener.updatePosition(position);
((MyViewHolder) holder).position.setText("" + position);
((MyViewHolder) holder).title.setText(dataList.get(position));
int valueToDisplay = 1;
if(positionToValueMap.containsKey(position)) {
valueToDisplay = positionToValueMap.get(position);
} else {
positionToValueMap.put(position, valueToDisplay);
}
((MyViewHolder) holder).valueView.setText("value: " + valueToDisplay);
}
#Override
public int getItemCount() {
return dataList.size();
}
private class MyViewHolder extends RecyclerView.ViewHolder {
private OnRecyclerItemClickListener onRecyclerItemClickListener;
private TextView position;
private TextView title;
private TextView valueView;
public MyViewHolder(View itemView, OnRecyclerItemClickListener onRecyclerItemClickListener) {
super(itemView);
itemView.setOnClickListener(onRecyclerItemClickListener);
this.onRecyclerItemClickListener = onRecyclerItemClickListener;
this.position = (TextView) itemView.findViewById(R.id.position);
this.title = (TextView) itemView.findViewById(R.id.title);
this.valueView = (TextView) itemView.findViewById(R.id.value_view);
}
}
private class OnRecyclerItemClickListener implements View.OnClickListener {
private int position = -1;
public void updatePosition(int position) {
this.position = position;
}
#Override
public void onClick(View v) {
int oldValue = positionToValueMap.get(position); // get current value
oldValue++; // increment
positionToValueMap.put(position, oldValue); // save current value
notifyItemChanged(position); // update clicked view so that it picks up the new saved value from the positionToValueMap in onBindViewHolder
}
}
}
RecyclerView item layout
<TextView
android:id="#+id/position"
android:layout_width="30dp"
android:layout_height="50dp"
android:textColor="#android:color/white"
android:gravity="center"
android:background="#android:color/holo_green_light"
android:layout_alignParentLeft="true"/>
<TextView
android:id="#+id/title"
android:layout_width="50dp"
android:layout_height="50dp"
android:textColor="#android:color/white"
android:gravity="center"
android:background="#android:color/holo_green_dark"
android:layout_toRightOf="#id/position" />
<TextView
android:id="#+id/value_view"
android:layout_width="match_parent"
android:layout_height="50dp"
android:textColor="#android:color/white"
android:gravity="center"
android:background="#android:color/holo_green_light"
android:layout_toRightOf="#id/title"
android:layout_alignParentRight="true"/>
</RelativeLayout>
And Activity to test it out
public class MainActivity extends AppCompatActivity {
private RecyclerView recyclerView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
recyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
recyclerView.setAdapter(new MyAdapter(getApplicationContext(), getSampleData()));
}
private static List<String> getSampleData() {
List<String> dataList = new ArrayList<>();
dataList.add("zero");
dataList.add("one");
dataList.add("two");
dataList.add("three");
dataList.add("four");
dataList.add("five");
dataList.add("six");
dataList.add("seven");
dataList.add("eight");
dataList.add("nine");
dataList.add("ten");
dataList.add("eleven");
dataList.add("twelve");
dataList.add("thirteen");
dataList.add("fourteen");
dataList.add("fifteen");
dataList.add("sixteen");
dataList.add("seventeen");
dataList.add("eighteen");
dataList.add("nineteen");
dataList.add("twenty");
return dataList;
}
}
activity layout
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/root_view"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="#+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/white"/>
</RelativeLayout>

unable to understand onClick event for multiple CardViews inside RecycleView

I looked up for the possible solutions but I could not figure out how to apply them in my case.
I am using a RecyclerView to display several CardViews inside it. Initially all cards have white background and I want to change the background color when a card is touched. Each CardView displays a name and an id as described in 'MyCards' class :
public class MyCards {
private String sName;
private int sId;
private boolean sPresent;
public String getName() {
return this.sName;
}
public MyCards(String sName, int sId, boolean sPresent) {
this.sName = sName;
this.sId = sId;
this.sPresent = sPresent;
}
public void setName(String t) {
this.sName = t;
}
public int getId() {
return sId;
}
public void setId(int id) {
this.sId = id;
}
public boolean isPresent() {
return sPresent;
}
public void setPresent(boolean present) {
this.sPresent = present;
}
}
I am making an ArrayList of these MyCards object in the 'Roster' class :
public class Roster extends ActionBarActivity{
private static final int READ_REQUEST_CODE = 42;
private static final String TAG = null;
private RecyclerView rObject;
private MyAdapter adapter;
String abc = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.roster_recycle);
rObject = (RecyclerView)findViewById(R.id.recycler_view);
LinearLayoutManager llm = new LinearLayoutManager(this);
llm.setOrientation(LinearLayoutManager.VERTICAL);
rObject.setLayoutManager(llm);
MyCards c1 = new MyCards("Abhinav", 123, true);
MyCards c2 = new MyCards("Abhishek", 13, false);
performFileSearch();
c1.setName("Abhinav");
c2.setName("Baba");
List<MyCards> cardList = new ArrayList<MyCards>();
cardList.add(c1);
cardList.add(c2);
adapter = new MyAdapter(Roster.this,cardList);
rObject.setAdapter(adapter);
}
The CardView is defined in the item_layout.xml file :
<android.support.v7.widget.CardView
android:id="#+id/card_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="10dp"
android:clickable="true"
android:foreground="?android:attr/selectableItemBackground"
card_view:cardCornerRadius="4dp" >
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="#+id/sName"
android:layout_width="match_parent"
android:layout_height="20dp"
android:gravity="center_vertical"
android:text="contact det"
android:textSize="14dp" />
<TextView
android:id="#+id/sId"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/sName"
android:layout_marginLeft="5dp"
android:layout_marginTop="10dp"
android:gravity="center_vertical"
android:text="Name"
android:textSize="10dp" />
<TextView
android:id="#+id/sPresent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/sId"
android:layout_marginLeft="5dp"
android:layout_marginTop="10dp"
android:gravity="center_vertical"
android:text="Present"
android:textSize="10dp" />
</RelativeLayout>
</android.support.v7.widget.CardView>
My question is : If I click on a card displaying data for 'c1' object then how can I identify that it was from 'c1' and not 'c2'. How do I use click handler in such cases where we display multiple cards?
I'm sorry if my question is too basic but I'm really stuck at it.
Thank you so much for your responses, they really helped. Finally I found a video on YouTube which explained the concept in a nice manner. I am posting the link so that others can also benefit if they get stuck. Here is the video -
see this :- https://www.youtube.com/watch?v=zE1E1HOK_E4
Take a look at this answer for using an onItemClickListener with a RecyclerView.
public class MyAdapter extends RecyclerView.Adapter {
Context mContext;
ArrayList<MyCard> mData;
public MyAdapter(Context context , ArrayList<MyCard> data ) {
mContext = context;
mData = data;
}
public class ViewHolder extends RecyclerView.ViewHolder{
private TextView sName, sId , sPresent;
public ViewHolder(View itemView) {
super(itemView);
sName = (TextView) itemView.findViewById(R.id.sName);
sId = (TextView) itemView.findViewById(R.id.sId);
sPresent = (TextView) itemView.findViewById(R.id.sPresent);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// your logic
}
});
}
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_layout , parent , false);
ViewHolder vh = new ViewHolder(v);
return vh;
}
#Override
public int getItemCount() {
return mData.size();
}
#Override
public void onBindViewHolder(ViewHolder holder, final int position) {
final MyCard card = mData.get(position);
holder.sName.setText(card.getName().toString());
holder.sId.setText(card.getId().toString());
holder.sPresent.setText(card.getPresent().toString());
}
}

Categories

Resources