I made SQL database and populated it with values. In TextView I need to show multiply result of specific rows.
I made SQL statement and I hope that is correct.
public List<Food> multiplyFat(){
String totalFat = "SELECT " +FoodEntry.COLUMN_FAT_TOTAL + " FROM " + FoodEntry.TABLE_NAME + " WHERE ( "
+FoodEntry.COLUMN_FAT_TOTAL + " * " + FoodEntry.COLUMN_GRAM + " ) > 0";
SQLiteDatabase db = this.getWritableDatabase();
List<Food> storeTotalFat = new ArrayList<>();
Cursor cursor = db.rawQuery(totalFat, null);
if (cursor.moveToFirst()){
do {
double fat = Double.parseDouble(cursor.getString(0));
storeTotalFat.add(new Food(fat));
} while (cursor.moveToNext());
}
cursor.close();
return storeTotalFat;
}
To be more clear I need to multiply values from row COLUMN_FAT_TOTAL with row COLUMN_GRAM and display result into the TextView. Or should I put these SQL statement:
String totalFat = "SELECT " +FoodEntry.COLUMN_FAT_TOTAL + " * " +FoodEntry.COLUMN_GRAM + " FROM " +FoodEntry.TABLE_NAME;
That is simplier way but I am not sure that it is correct way.
Anyhow I need to display this multiplyFat() function (result) into TextView. Any help or advice would be really helpfull.
public List multiplyFat(){
String totalFat = "SELECT " +FoodEntry.COLUMN_FAT_TOTAL + " FROM " + FoodEntry.TABLE_NAME + " WHERE ( "
+FoodEntry.COLUMN_FAT_TOTAL + " * " + FoodEntry.COLUMN_GRAM + " ) > 0";
The above works perfectly in MySQL, I just tried it.
SQLiteDatabase db = this.getWritableDatabase(); --> db = this.getReadableDatabase();
Since you are not changing anything in the SQLite database you want a '.getReadableDatbase();' not '.getWritableDatabase();'
List<Food> storeTotalFat = new ArrayList<>();
Cursor cursor = db.rawQuery(totalFat, null);
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
do {
double fat = Double.parseDouble(cursor.getString(0));
storeTotalFat.add(new Food(fat));
} cursor.moveToNext();
}
cursor.close();
return storeTotalFat;
}
See how I first moved to the first index, then I ask it to continue in a while loop until it has reached the final element in the SQL results. Your way was not actually incrementing the cursor, it would have only been able to add the first result to the storeTotalFat ArrayList.
-------- part 2 ---------
Now let's pretend we are back in the activity, woo!
Let's say there is a class variable reference to the database helper and add a new ArrayList to house the results from the query result we just gained.
DBHelper myDBhelper = DBHelper.getInstance(MainActivity.this)
ArrayList<String> sqlResultArray = new ArrayList<>();
If you want a Recyclerview you make a separate RviewAdapter class, in your case FoodFatRecyclerViewAdapter and add the following
RecyclerView rv = (RecyclerView) findViewById(R.id.foodFatRecView);
LinearLayoutManager llm = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
recyclerView.setLayoutManager(llm);
FoodFatRecyclerViewAdapter foodFatAdapter = new FoodFatRecyclerViewAdapter(MainActivity.this, sqlResultArray);
rv.setAdapter(foodFatAdapter);
Now as for the adding of the result to the textview create a new class called FoodFatRecyclerViewAdapter
public class FoodFatRecyclerViewAdapter extends RecyclerView.Adapter<FoodFatViewHolder> {
ArrayList<String> mFoodFatItems;
Context mContext;
public FoodFatRecyclerViewAdapter(Context context, ArrayList<String> array) {
mContext = context;
mFoodFatItems = array;
}
#Override
public FoodFatViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.this_xml_layout_will_describe_the_arrangement_of_the_indi_item_in_the_list_not_the_master_view, parent, false);
FoodFatViewHolder recyclerView = new FoodFatViewHolder(view);
return recyclerView;
}
#Override
public void onBindViewHolder(FoodFatViewHolder holder, final int position) {
holder.mFatTotalTextView.setText(mFoodFatItems.get(position));
}
#Override
public int getItemCount() {
return mFoodFatItems.size();
}
}
Now the final piece to the puzzle, the View Holder so create a class called FoodFatViewHolder
public class FoodFatViewHolder extends RecyclerView.ViewHolder{
TextView mFatTotalTextView;
public FoodFatViewHolder(View itemView) {
super(itemView);
mFatTotalTextView = (TextView) itemView.findViewById(R.id.the_textview_id_within_the_individ_item_in_rv_xml_layout);
}
}
Voila! It should work
You need to show the multiplication total then you shouldn't do a select on COLUMN_FAT_TOTAL. Instead you should do the computation in your select query and store that computation in an alias. You can then use that alias as a result.
Modify your query as below
String totalFat = "SELECT " +FoodEntry.COLUMN_FAT_TOTAL + " * " + FoodEntry.COLUMN_GRAM + "AS Result FROM " + FoodEntry.TABLE_NAME";
You are on the right track. Do the math in the database if it is easy and straight forward, which this example is.
Might I suggest the following (similar to kapsym answer) for your sql statement:
String totalFat = "SELECT " + FoodEntry.COLUMN_FAT_TOTAL + ", " + FoodEntry.COLUMN_GRAM + "," FoodEntry.COLUMN_FAT_TOTAL + " * " + FoodEntry.COLUMN_GRAM + "AS TotalFat FROM " + FoodEntry.TABLE_NAME + " WHERE ( " + FoodEntry.COLUMN_FAT_TOTAL + " * " + FoodEntry.COLUMN_GRAM + " ) > 0";
You should study the basics of MySQL : https://www.tutorialspoint.com/mysql/mysql-select-query.htm
After the SELECT, you add column names that you want to retrieve and not expressions.
For your case, Use this Query to get all fat_total & gram entries :
String totalFat = "SELECT " + FoodEntry.COLUMN_FAT_TOTAL + "," + FoodEntry.COLUMN_GRAM + " FROM " + FoodEntry.TABLE_NAME;
Then you retrieve fatTotal * gram for each cursor, multiply it and feed it into your storeTotalFat array based on (!= 0) condition.
Cursor cursor = db.rawQuery(totalFat, null);
if (cursor.moveToFirst()){
do {
double fat = Double.parseDouble(cursor.getString(0));
double gram= Double.parseDouble(cursor.getString(1));
if (fat * gram != 0)
storeTotalFat.add(new Food(fat * gram));
} while (cursor.moveToNext());
}
Related
I created an adapter for my ListView that's displaying a data from my SQLite database, the problem is that in the ListView, I have 5 times the same line:
My adapter's code:
public class MyAdapter extends ArrayAdapter<Historique> {
private LayoutInflater mInflat;
private ArrayList<Historique> hist = new ArrayList<Historique>();
private int mVRessId;
public MyAdapter (Context context, int ressId, ArrayList<Historique> hists){
super(context,ressId,hists);
this.hist =hists;
mInflat = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mVRessId =ressId;
}
public View getView(int position, View convertedView, ViewGroup parents){
convertedView = mInflat.inflate(mVRessId,null);
Historique histor = hist.get(position);
if (histor != null){
TextView name = (TextView) convertedView.findViewById(R.id.hnom);
TextView quest = (TextView) convertedView.findViewById(R.id.hques);
TextView rep = (TextView) convertedView.findViewById(R.id.hrep);
TextView date = (TextView) convertedView.findViewById(R.id.hdate);
if (name != null){
name.setText(""+histor.getNom()+ ": "+histor.getLigne());
}
if (quest != null){
quest.setText(histor.getQuest());
}
if (rep != null){
rep.setText(histor.getRep());
}
if (date != null){
date.setText(histor.getDate().toString());
}
}
return convertedView;
}
}
The ListView must display the list, and here's the code:
final MyAdapter adapter = new MyAdapter (this, R.layout.adapter_view_layout,histList);
mCsr = openhelper.getTableHistoAsCursor();
int rows = mCsr.getCount();
if (rows == 0 ){
Toast.makeText(Historian.this, "Pas d'historique disponible", Toast.LENGTH_SHORT).show();
} else {
while (mCsr.moveToNext()){
histo = new Historique(mCsr.getString(0).toString(),mCsr.getString(1).toString(), mCsr.getString(2).toString(),mCsr.getString(3).toString(),mCsr.getString(4).toString());
histList.add(histo);
}
}
mListView .setAdapter(adapter);
The getTableHisto is a function that returns a cursor from my SQLite Modelhelper:
public Cursor getTableHistoAsCursor() {
SQLiteDatabase db = this.getReadableDatabase();
Cursor data = db.rawQuery(" SELECT Q." + KEY_QUESTION + " ,L." + KEY_LIGNE + " , U." + KEY_NOM + " , A." + KEY_DATE + " , A. " + KEY_REPONSE + " from "+ TABLE_LIGNE + " L, " + TABLE_QUESTION + " Q, " + TABLE_USER + " U, " + TABLE_ANSWER + " A WHERE Q." + KEY_ID_QUESTION + " = A." + KEY_ID_QUESTION + " AND A." + KEY_MATRICULE + " = U." + KEY_MATRICULE, null);
return data;
}
In the first time, I thought that in the insert I was doing something wrong and it goes 5 times in the database, so I've created an activity to try to get the number of inserts with a Select count();
And I saw that the result that I'm getting is the true result, I don't insert 5 times the same line, but the adapter is displaying it 5 times in 5 lines.
If you have any idea that can help me, I would be thankful.
thanks.
//Initialize my adapter after populating the list
histList.add(histo);
Adapter is only initialized after populating values in the Array List
not with null values.
final MyAdapter adapter = new MyAdapter (this, R.layout.adapter_view_layout,histList);
mListView .setAdapter(adapter);
I got it, the problem is solved, in case someone has the same problem, the loop wasn't good so I changed
else {
while (mCsr.moveToNext()){
by
else {
if (mCsr != null){
mCsr.moveToFirst();
I want to make above type of RecyclerView (in my case). In above sample pic, the expenses show in red colours with zebra lines and income shows in green colours. I've write code for expense table values and successfully shown in RecyclerView. Now I want to show income from income table and make view same as sample pic. kindly help.
RecyclerView with expense values:
arrayListExpense = new ArrayList<>();
AdapterViewItems adapter = new AdapterViewItems(MainActivity.this, arrayListExpense);
recyclerView = (RecyclerView) findViewById(R.id.view_item_recycle_view);
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext());
recyclerView.setLayoutManager(mLayoutManager);
recyclerView.setAdapter(adapter);
Cursor cursor = db.selectExpense();
cursor.moveToFirst();
if (cursor.getCount() == 0) {
Toast.makeText(this, "Empty list", Toast.LENGTH_SHORT).show();
} else {
for (int i = 0; i < cursor.getCount(); i++) {
HashMap<String, Object> hm = new HashMap<>();
hm.put(ID_EXPENSE, cursor.getString(cursor.getColumnIndex(ID_EXPENSE)));
hm.put(NAME_EXPENSE, cursor.getString(cursor.getColumnIndex(NAME_EXPENSE)));
long valueExpense = cursor.getLong(cursor.getColumnIndex(VALUE_EXPENSE));
showExpense(valueExpense);
hm.put(VALUE_EXPENSE, String.valueOf(valueExpense));
hm.put(DATE_EXPENSE, Utility.dateFormat(cursor.getLong(cursor.getColumnIndex(DATE_EXPENSE))));
String id = cursor.getString(cursor.getColumnIndex(TYPE_ID_EXPENSE));
hm.put("type", db.selectTypeById(id));
arrayListExpense.add(hm);
cursor.moveToNext();
}
cursor.close();
}
Database:
Cursor selectExpense() {
Cursor cursor = null;
try {
SQLiteDatabase db = this.getWritableDatabase();
cursor = db.rawQuery("SELECT " + ID_EXPENSE + "," + NAME_EXPENSE + "," + VALUE_EXPENSE
+ "," + DATE_EXPENSE + "," + TYPE_ID_EXPENSE + " FROM " + TABLE_EXPENSE
+ " ORDER BY " + DATE_EXPENSE + " DESC", null);
} catch (Exception e) {
Log.d("selectExpenses", " error " + e.getMessage());
}
return cursor;
}
All you need is getItemViewType which will allow you to inflate multiple views within a recyclerview.
Example : see this or this
Use a tag that gives you information like it is expanses or inform.
add that tag in hashmap.
if(expanses){ // use variable to check expanses or income
hm.put(INFO_EXPENSE_INCOME, "red");
}else{
hm.put(INFO_EXPENSE_INCOME, "green");
}
and in bindViewHolder get the hashmap value and setTextColor accordingly.
I have just started coding an Android App using Android Studio 2.1 and my app was sort of an offline messaging - this is using SQLite Database (basically compose of two tables message and contact).
I am now in my last activity where I need to populate a list of message exchange from the contacts created. I was able to list them but without aesthetics. I would like to set different setBackgroundResource whenever the type is either a LEFT or RIGHT but was struggling to apply it.
Below is my code:
MessageRepo - the SQLite DBhelper:
public ArrayList<HashMap<String, String>> getMessageListById(int fromid, int toid) {
SQLiteDatabase db = helper.getWritableDatabase();
String toquery = "SELECT " + MessageModel.messageId +
", " + MessageModel.fromId +
", " + MessageModel.toId +
", " + MessageModel.messageContent +
", 'RIGHT' AS type FROM " + MessageModel.tableMessage +
" WHERE " + MessageModel.toId +
" = ? AND " + MessageModel.fromId +
" = ? ";
String fromquery = "SELECT " + MessageModel.messageId +
", " + MessageModel.fromId +
", " + MessageModel.toId +
", " + MessageModel.messageContent +
", 'LEFT' AS type FROM " + MessageModel.tableMessage +
" WHERE " + MessageModel.fromId +
" = ? AND " + MessageModel.toId +
" = ? ";
String query = toquery +
" UNION " + fromquery +
" ORDER BY " + MessageModel.messageId;
ArrayList<HashMap<String, String>> messageList = new ArrayList<HashMap<String, String>>();
Cursor cursor = db.rawQuery(query, new String[]{String.valueOf(fromid), String.valueOf(toid), String.valueOf(fromid), String.valueOf(toid)});
if (cursor.moveToFirst()) {
do {
HashMap<String, String> messages = new HashMap<String, String>();
messages.put("messageId", cursor.getString(0));
messages.put("messageFromId", cursor.getString(1));
messages.put("messageToId", cursor.getString(2));
messages.put("messageContent", cursor.getString(3));
messages.put("type", cursor.getString(4));
messageList.add(messages);
} while (cursor.moveToNext());
}
cursor.close();
db.close();
return messageList;
}
Message Activity - this will display in a ListView but not working as I was intending it to display:
ArrayList<HashMap<String, String>> messageList = messagehandler.getMessageListById(_fromid, _toid);
if (messageList.size() != 0) {
ListView listView = getListView();
if(messageList.contains("RIGHT")) {
listView.setBackgroundResource(R.drawable.right);
} else {
listView.setBackgroundResource(R.drawable.left);
}
ListAdapter adapter = new SimpleAdapter(MessageDetailActivity.this, messageList, R.layout.message, new String[]{"messageFromId", "messageToId", "messageContent"}, new int[]{R.id.FromId, R.id.ToId, R.id.message});
setListAdapter(adapter);
}
I've checked a lot of posts and I can't seem to make it work for me:
The constructor ArrayAdapter>>(Context, int, ArrayList>) is undefined
Android Alternate row Colors in ListView
Thanks a lot in advance!
After researching a bit more. I finally found the answer by opting to use List and a setter/getter class:
public class MessagesAdapter extends ArrayAdapter<ContactsAndMessages> {
public MessagesAdapter(Context context, List<ContactsAndMessages> contacts) {
super(context, 0, contacts);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ContactsAndMessages contact = getItem(position);
Typeface typeface = Typeface.createFromAsset(getContext().getAssets(), "fonts/helvetica.ttf");
if(convertView == null) {
if (contact.type.equalsIgnoreCase("me")) {....
I'm trying to load a database column with a cursor result for my quiz app. The reason for this is that i want to populate a list view with the questions in a each category so i set up this:
public void putValues(){
for (int i = 0; i < 18; i++) {
Cursor contentCursor = null;
contentCursor = mDB
.rawQuery("select count(*) from questions_en where used = 0 and category" + " = " + i, null);
if(contentCursor.getCount() >0 )
contentCursor.moveToFirst();
if (contentCursor.isAfterLast()) {
contentCursor.close();
mDB.close();
return;
}
int contentCursorInt = contentCursor.getInt(0);
Cursor upateCursor = null;
upateCursor = mDB.rawQuery("update categories_en set questions_count" + " = " + contentCursorInt + " where " + "_id" + " = " + i, null);
upateCursor.moveToNext();
upateCursor.close();
contentCursor.close();
}
}
so that when the user clicks an answer (on the question screen) used becomes 1(or any non-zero value) the query result changes. The above code works fine the very first time. Because i haven't set up the question screen, i added this query:
public void test(){
Cursor cus = mDB.rawQuery("update questions_en set used = 1 where category = 2 and _id = 146", null);
cus.close();
}
to my DB Adapter and then called this method from my MainActivty
#Override
public void onClick(View v) {
TestAdapter mTest = new TestAdapter(MainActivity.this);
mTest.createDatabase();
mTest.open();
mTest.test();
Log.d(DBHelper.TAG, " Worked ");
mTest.close();
}
});
But when i click on this and go to my ListActivity I expected the value of category 2 to have changed since the query had just been carried out again. But it doesn't reduce. I pulled out my DB from DDMS(file explorer) and i found out that the query to _id = 146 actually didn't change used to 1. Any help on what may be the cause?
Solve the problem with the help of this.
I just changed this:
public void test(){
Cursor cus = mDB.rawQuery("update questions_en set used = 1 where category = 2 and _id = 146", null);
cus.close();
}
to this
public void test(){
int id = 3;
ContentValues data = new ContentValues();
data.put(DBHelper.KEY_USED, "1");
mDB.update(DBHelper.KEY_QUESTIONS_TABLE, data, DBHelper.KEY_ID + " = " + id , null);
}
How do I retrieve the data on all columns from an INNER JOIN result? I use this query:
SELECT course.course_title,
course.course_body,
course. course_image,
instructor.instructor_title,
instructor.instructor_body,
instructor.instructor_photo
FROM course
INNER JOIN instructor
ON course.course_instructor1=instructor.instructor_nid
WHERE course_id=4
and this is the equivalent variable COURSE_OUTLINE that i'll be using to execute
String COURSE_OUTLINE =
"SELECT " + Qualified.COURSE_TITLE + ", "
+ Qualified.COURSE_BODY + ", "
+ Qualified.COURSE_IMAGE + ", "
+ Qualified.INSTRUCTOR_TITLE + ", "
+ Qualified.INSTRUCTOR_BODY + ", "
+ Qualified.INSTRUCTOR_IMAGE + ", " +
"FROM " + Tables.COURSE_JOIN_INSTRUCTOR +
"WHERE " + CourseColumns.COURSE_ID +
"=?";
In my code,
Cursor cur = mSqliteDb.rawQuery(SubQuery.COURSE_OUTLINE, new String[] {position});
This gives 1 record. I know how to retrieve data from a specific column but I'm not sure how to retrieve it from all columns.
this is the code I use to retrieve data from a specific column
public String getCourseImage(int position) {
String image = "";
String pos = Integer.toString(position);
Cursor cur = mSqliteDb.rawQuery(SelectQuery.ALL_COURSES, new String[] {pos});
if (cur != null) {
if (cur.moveToFirst()) {
do {
image = cur.getString(cur.getColumnIndex(CourseColumns.COURSE_IMAGE));
} while (cur.moveToNext());
}
cur.close();
}
return image;
}
My intention is mapping each data in a column to a View
getColumnNames gives you an array with all columns... if that's what you're asking. It's kind of hard to tell.