Display a SQLite colum one value after another - java

I'm really strugling to figure this out and had not found an answer or a way to do it.
What I'm trying to do is having questions that are saved in a SQLite colum to be displayed in a TextView one after another until they finish.
What I have done so far on the main Activity
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mDatabaseHelper = new DatabaseHelper(this);
btn1star = (Button) findViewById(R.id.btn1star);
btn2star = (Button) findViewById(R.id.btn2star);
btn3star = (Button) findViewById(R.id.btn3star);
mListview = (ListView) findViewById(R.id.qlistview);
qTextView = (TextView) findViewById(R.id.qTextView);
questionsListView();
}
private void questionsListView() {
Cursor data = mDatabaseHelper.getData();
data.moveToFirst();
qTextView.setText(data.getString(1));
}
public void VoteClick(View view){
mDatabaseHelper.getReadableDatabase();
Cursor data = mDatabaseHelper.getData();
if (data.getCount() >=1){
for (int i = 0; i< data.getCount(); i++) {
data.moveToNext();
Log.i("Counted Questions are: ", String.valueOf(data.getCount()));
qTextView.setText(data.getString(1));
}
}
}
private void toastmessage (String message){
Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
}
}
I'm able to display the first and when i click the button the last question
I'm unable to display the questions between.
Any tip or suggestion?

In your VoteClick method you do your getReadableDatabase, this is too late, move this line into onCreate method. You must open the database before reading from it (in questionsListView).
mDatabaseHelper.getReadableDatabase();//move to onCreate
add this:
startManagingCursor(data);
data.moveToFirst();
BEFORE the line:
if (data.getCount() >=1){

Hello found a solution to my problem
It turns out that i have to make a new int variable
Get its value from the first id
and incrise this by one at the end of each button press until i reach the last cursor place whhere i move the cursor to the first position
public void VoteClick(View view) {
Cursor data = mDatabaseHelper.getData();
data.moveToPosition(q);
data.moveToNext();
qTextView.setText(data.getString(1));
while (data.isLast()) {
data.moveToFirst();
q = data.getPosition();
}
q = q+1;
}

Related

activity only loads data for first ever pressed index after reloading app

I have created Activity with a listView which uses setOnItemClickListener to determine which index has been pressed. Then it should pass the data into the next activity based on the selected index.
Passing of the values works, but it only works for the first listView index pressed after the app is reloaded.
To make it more clear. When the app is loaded I can press on any index of the ListView which will pass the data to the next Activity and display it correctly, but then when I go back to the ListView and select different index it still displays the same data from the previous index without updating it. Therefore, I have to reload the app to get new index results displayed.
Here is my ViewListActivity:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_view_artist);
artistList = (ListView) findViewById(R.id.artistList);
databasehandler = new SqliteHandler(ViewArtistActivity.this);
allArtists = databasehandler.getAllArtists();
artistName = new ArrayList<>();
singleArtistDetails = new ArrayList<>();
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
if (allArtists.size() > 0) {
for (int i=0; i < allArtists.size(); i++) {
ArtistModel artistModel = allArtists.get(i);
artistName.add(artistModel.getArtistName());
}
}
adapter = new ArrayAdapter(ViewArtistActivity.this, android.R.layout.simple_list_item_1, artistName);
artistList.setAdapter(adapter);
artistList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
ArtistModel artistModel = allArtists.get(position);
singleArtistDetails.add(artistModel.getArtistName());
singleArtistDetails.add(artistModel.getArtistDOB());
singleArtistDetails.add(artistModel.getArtistBiography());
Intent intent = new Intent(ViewArtistActivity.this, SavedArtistDetailsActivity.class);
intent.putExtra("NAME", singleArtistDetails.get(0));
intent.putExtra("DOB", singleArtistDetails.get(1));
intent.putExtra("BIOGRAPHY", singleArtistDetails.get(2));
startActivity(intent);
}
});
}
Here is my code for displaying selected index results Activity:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_saved_artist_details);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
artistSavedNameLbl2 = (TextView) findViewById(R.id.artistSavedNameLbl2);
artistSavedDOBLbl2 = (TextView) findViewById(R.id.artistSavedDOBLbl2);
artistSavedBiographyLbl2 = (TextView) findViewById(R.id.artistSavedBiographyLbl2);
btnDeleteDetails = (Button) findViewById(R.id.btnDeleteDetails);
updateUI();
}
private void updateUI() {
artistSavedNameLbl2.setText(getIntent().getStringExtra("NAME"));
artistSavedDOBLbl2.setText(getIntent().getStringExtra("DOB"));
artistSavedBiographyLbl2.setText(getIntent().getStringExtra("BIOGRAPHY"));
}
Do one thing , initialize [not saying declare] your array list singleArtistDetails inside the onClick method, before adding any values to it.
like
singleArtistDetails = new ArrayList();
Hope this will help.

Change SQL query based on button action

I have a listview that displays all the items in my database. I am trying to create a button that will change the data displayed to only show items that match today's date.
What is the best way to change the query that is being run in the app based on a button push and update the listview?
I've played with setting a flag in the onclick() method paired with if-else statements that held the query call, but it did not seem to switch which was being called.
The flag is the boolean filterToday. set in the onClickListener of todayButton.
public class MainActivity extends AppCompatActivity {
public final static String KEY_EXTRA_CONTACT_ID = "KEY_EXTRA_CONTACT_ID";
private ListView listView;
DBHelper dbHelper;
boolean filterToday;
Cursor cursor;
String [] columns;
int [] widgets;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button addButton = (Button) findViewById(R.id.addNew);
addButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(MainActivity.this, AddTaskActivity.class);
intent.putExtra(KEY_EXTRA_CONTACT_ID, 0);
startActivity(intent);
}
});
Button todayButton = (Button) findViewById(R.id.today);
todayButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
filterToday = true;
}
});
dbHelper = new DBHelper(this);
if(filterToday == true){
Calendar cal = Calendar.getInstance();
DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
String date = df.format(cal.getTime());
Toast.makeText(this,date,Toast.LENGTH_LONG).show();
cursor = dbHelper.getTodaysTasks(date);
}
else{
cursor = dbHelper.getAllTasks();
}
columns = new String[] {
DBHelper.TASK_COLUMN_NAME,
DBHelper.TASK_COLUMN_TYPE,
DBHelper.TASK_COLUMN_DATE
};
widgets = new int[] {
R.id.taskName,
R.id.taskType,
R.id.taskDate
};
SimpleCursorAdapter cursorAdapter = new SimpleCursorAdapter(this, R.layout.task_info,
cursor, columns, widgets, 0);
listView = (ListView)findViewById(R.id.listView1);
listView.setAdapter(cursorAdapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> listView, View view,
int position, long id) {
Cursor itemCursor = (Cursor) MainActivity.this.listView.getItemAtPosition(position);
int taskID = itemCursor.getInt(itemCursor.getColumnIndex(DBHelper.TASK_COLUMN_ID));
Intent intent = new Intent(getApplicationContext(), AddTaskActivity.class);
intent.putExtra(KEY_EXTRA_CONTACT_ID, taskID);
startActivity(intent);
}
});
}
}
These are the two queries I am trying to switch between:
public Cursor getAllTasks() {
SQLiteDatabase db = this.getReadableDatabase();
Cursor res = db.rawQuery( "SELECT * FROM " + TASK_TABLE_NAME, null );
return res;
}
public Cursor getTodaysTasks(String date){
SQLiteDatabase db = this.getReadableDatabase();
Cursor res = db.rawQuery("SELECT * FROM " + TASK_TABLE_NAME + " WHERE " +
TASK_COLUMN_DATE + " =?", new String[]{date});
return res;
}
OK so the first thing to notice is that your update filterToday = true; inside the onclick listener, the if(filterToday == true){...} outside doesn't know that. That part is only executed once in the oncreate()
If you'd like to perform that action I suggest a small change.. like below
Create a seperate function outside for the data loading
private void LoadMyData() {
if(filterToday == true){
Calendar cal = Calendar.getInstance();
DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
String date = df.format(cal.getTime());
//you might need to update this line
//Toast.makeText(this,date,Toast.LENGTH_LONG).show();
//assume dbHelper is ready at this point
cursor = dbHelper.getTodaysTasks(date);
}
else{
cursor = dbHelper.getAllTasks();
}
}
Call this function inside onclick listner
filterToday = false;//initialize to false if necessary
todayButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
filterToday = !filterToday ;//by doing it like this you can switch back and forth. add/check extra logic if necessary
LoadMyData();
}
});
LoadMyData(); //Call this outside in the oncreate to load the data initially
I'm not suggesting a code improvement here. Just changes to what you already have. Hope it helps.
There were two issues that I ran into, the first was comparing a string to to the SQL string[], which meant while the comparison was working, it did not behave as I expected. Once fixing this issue was updating the ListView object. This was handled by creating a new adapter and attaching it to ListView, which then updates itself.
Per this answer: Refresh Current Fragment (ListView Data) remaining in the same activity
The other option was to call notifyDataSetChanged() on the adapter, but this did not work well with the way I had my program set up.

Overriding default screen contents in android

I am developing a quiz app and my activity looks like this:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_quiz);
//click this button to go to the next question
mButton = (Button)findViewById(R.id.nextButton);
//open the DB
openDB();
//Check if the table has data
if(!(myDb.checkDataExists())) {
insertRows();
}
//display a random question
displayQuestion();
}
private void displayQuestion() {
randomNumber = getRandomNumber();
//check if number used or not
if (isNumberNew(String.valueOf(randomNumber))) {
Cursor cursor = myDb.getRow(randomNumber);
displayRecordSet(cursor, optionAnswer);
mOptionButton1.setBackgroundColor(color);
mOptionButton2.setBackgroundColor(color);
mOptionButton3.setBackgroundColor(color);
mOptionButton4.setBackgroundColor(color);
flag = true;
}
}
private void displayRecordSet(Cursor cursor, Map<String, String> optionAnswer) {
int id = 0;
String question = "", option = "", rightAnswer = "";
ArrayList<String> optionList = new ArrayList<String>();
mImageView = (ImageView)findViewById(R.id.storyImageView);
mQuestionTextView = (TextView)findViewById(R.id.questionTextView);
mOptionButton1 = (Button)findViewById(R.id.button);
mOptionButton2 = (Button)findViewById(R.id.button2);
mOptionButton3 = (Button)findViewById(R.id.button3);
mOptionButton4 = (Button)findViewById(R.id.button4);
}
if (cursor.moveToFirst()) {
do {
id = cursor.getInt(0);
question = cursor.getString(1);
option = cursor.getString(3);
rightAnswer = cursor.getString(5);
optionList.add(option);
optionAnswer.put(option,rightAnswer);
} while (cursor.moveToNext());
mQuestionTextView.setText(question);
mOptionButton1.setText(optionList.get(0));
mOptionButton2.setText(optionList.get(1));
mOptionButton3.setText(optionList.get(2));
mOptionButton4.setText(optionList.get(3));
}
cursor.close();
}
The displayQuestion method is supposed to get a random question from the db and then override the values of the option buttons and the question text view. However, when the app starts, the first question is still the one that I hardcoded in my view. In other words, when I call the setContentView(R.layout.activity_quiz); ... I am putting default values in for the option buttons and the question text view. But, I don't want to display those values because they are just place holders. I want to display the question from the database, which I get through dipslayQuestion method.
Does anyone know how to fix this?
There doesn't seem to be enough info to help you. What does displayRecordSet do and how are mOptionButtonX defined? Maybe you intended to change the text of buttons, not the background color?
Also, 2 things. Try to use more descriptive variable names instead of "flag" and such. Secondly, you shouldn't hardcode text into layout files you never want to use. Just set the text to "", you'll overwrite it anyway.

Text view if statement not working

Can anyone help me work out where I'm going wrong here. On the button click the media player plays one of the mfiles at random and I'm trying to set a textview depending on which file was played. Currently the setText if statements only match the audio playing half the time. Really not sure where I'm going wrong here.
private final int SOUND_CLIPS = 3;
private int mfile[] = new int[SOUND_CLIPS];
private Random rnd = new Random();
MediaPlayer mpButtonOne;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mfile[0] = R.raw.one;
mfile[1] = R.raw.two;
mfile[2] = R.raw.three;
//Button setup
Button bOne = (Button) findViewById(R.id.button1);
bOne.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
final TextView textOne = (TextView)findViewById(R.id.textView1);
mpButtonOne = MediaPlayer.create(MainActivity.this, mfile[rnd.nextInt(SOUND_CLIPS)]);
if (mpButtonOne==null){
//display a Toast message here
return;
}
mpButtonOne.start();
if (mfile[rnd.nextInt(SOUND_CLIPS)] == mfile[0]){
textOne.setText("one");
}
if (mfile[rnd.nextInt(SOUND_CLIPS)] == mfile[1]){
textOne.setText("two");
}
if (mfile[rnd.nextInt(SOUND_CLIPS)] == mfile[2]){
textOne.setText("three");
}
mpButtonOne.setOnCompletionListener(new soundListener1());
{
}
So just to clarify the problem I am having is that the setText only matches the audio occasionally, not on every click. The rest of the time it displays the wrong text for the wrong audio.
You are choosing another random file
mfile[rnd.nextInt(SOUND_CLIPS)]
set that to a variable in onClick() then check against that variable in your if statement
public void onClick(View v) {
int song = mfile[rnd.nextInt(SOUND_CLIPS)];
final TextView textOne = (TextView)findViewById(R.id.textView1);
mpButtonOne = MediaPlayer.create(MainActivity.this, song);
if (song == mfile[0]){
textOne.setText("one");
}
Edit
To make it a member variable so you can use it anywhere in the class, just declare it outside of a method. Usually do this before onCreate() just so all member variables are in the same place and it makes your code more readable/manageable.
public class SomeClass extends Activity
{
int song;
public void onCreate()
{
// your code
}
then you can just initialize it in your onClick()
public void onClick(View v) {
song = mfile[rnd.nextInt(SOUND_CLIPS)];
final TextView textOne = (TextView)findViewById(R.id.textView1);
mpButtonOne = MediaPlayer.create(MainActivity.this, song);

Caught in an infinite loop

I'm trying to perform a check on some information in a database. If i run the following code without it being in a loop it runs fine, but only checking the first row, what i need it to do is to check the names and dates for each row.
If i understand the while loop correctly it would move my cursor to the next row then just run the code again. Can anyone see why this is looping until my program crashes?
while (cursor.moveToNext()) {
String titlefromdb = cursor.getString(3);
if (strTitle.equals(titlefromdb)&& cursor.getString(1).equals(dateselforap)) {
Log.d("insidematch", "date and title matched");
final Dialog matchdiag = new DialogCW2Organisor.this);
matchdiag.setContentView(R.layout.apptmatch);
matchdiag.setTitle("View/Edit Appointment");
matchdiag.setCancelable(true);
TextView matchtxt = (TextView) matchdiag.findViewById(R.id.matchtxt);
matchtxt.setText("Appointment \""+ titlefromdb + "\" already exists, please choose a different event title");
Button btnmatchok = (Button) matchdiag.findViewById(R.id.btnmatch);
btnmatchok.setOnClickListener(new OnClickListener() {
//on click for cancel button
#Override
public void onClick(View v) {
matchdiag.dismiss();}
});
matchdiag.show();
} else {
addAppt(strTime, strTitle, strDet);
cursor = getAppts();
dialog.dismiss();
}
}
Try moving to the first record before calling moveToNext().
Move your functionality into a do/while loop so you can still grab the first record
if (!cursor.moveToFirst())
return; //nothing to do since the cursor is empty
do
{
String titlefromdb = cursor.getString(3);
if (strTitle.equals(titlefromdb)&& cursor.getString(1).equals(dateselforap)) {
Log.d("insidematch", "date and title matched");
final Dialog matchdiag = new DialogCW2Organisor.this);
matchdiag.setContentView(R.layout.apptmatch);
matchdiag.setTitle("View/Edit Appointment");
matchdiag.setCancelable(true);
TextView matchtxt = (TextView) matchdiag.findViewById(R.id.matchtxt);
matchtxt.setText("Appointment \""+ titlefromdb + "\" already exists, please choose a different event title");
Button btnmatchok = (Button) matchdiag.findViewById(R.id.btnmatch);
btnmatchok.setOnClickListener(new OnClickListener() {
//on click for cancel button
#Override
public void onClick(View v) {
matchdiag.dismiss();
}
});
matchdiag.show();
} else {
addAppt(strTime, strTitle, strDet);
cursor = getAppts();
dialog.dismiss();
}
} while (cursor.moveToNext());
I have also run into the infinite loop problem, which really baffled me as well, since a while !moveToNext() loop should definitely finish.
However, the workaround is to use a for loop over the length of the cursor, and process each cursor.moveToPosition(i).
for (int i = 0; i <= cursorLen; i++) {
if (!cursor.moveToPosition(i)) {
return;
}
// process your cursor
}
I feel like this must be a bug with the Cursor implementation, because a while loop over cursor.moveToNext() should always finish.

Categories

Resources