Listview showing duplicate values on execution - android

When I try to load data from SQLite database to my ListView each item is duplicated.
I double checked my database values while getting to the Cursor: there is no redundant data in it. But when I try to show in ListView I get duplicate entries. I tried other questions from this section, but nothing can solve my problem. I know that hash set can reduce redundant data. But I have no idea about how to use it.
Here is my code:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.distance);
list = (ListView) findViewById(R.id.list);
openAndQueryDatabase();
displayResultList();
}
private void displayResultList() {
String[] fromwhere = { "code","name" };
int[] viewswhere = { R.id.id,R.id.name};
ADAhere = new SimpleAdapter(Distance.this, datas,
R.layout.simple_list_row, fromwhere, viewswhere);
list.setAdapter(ADAhere);
list.setOnItemClickListener(this);
}
private void openAndQueryDatabase() {
try {
datas = new ArrayList<Map<String, String>>();
DatabaseHelper dbHelper = new DatabaseHelper(this.getApplicationContext());
newDB = dbHelper.getWritableDatabase();
Cursor c = newDB.rawQuery("select distinct cust_code,cust_name from customer", null);
Log.v("detailss", c.toString());
while (c.moveToNext()){
HashMap<String, String> datanums = new HashMap<String, String>();
String custcode = c.getString(c.getColumnIndex("cust_code"));
datanums.put("code", custcode);
datas.add(datanums);
String name = c.getString(c.getColumnIndex("cust_name"));
datanums.put("name", name);
datas.add(datanums);
}
}
catch (SQLiteException se ) {
Log.e(getClass().getSimpleName(), "Could not create or Open the database");
}
}

Let's take a look at how you transfer data from the Cursor 'c' to the ArrayList<Map<String, String>> 'datas':
while (c.moveToNext()){
HashMap<String, String> datanums = new HashMap<String, String>();
String custcode = c.getString(c.getColumnIndex("cust_code"));
datanums.put("code", custcode);
datas.add(datanums);
String name = c.getString(c.getColumnIndex("cust_name"));
datanums.put("name", name);
datas.add(datanums);
}
Each Cursor position belongs to one database table row. (If we think of query results as very short-lived tables this is even true for queries with JOIN etc.)
In your code, we see that for each row you add a Map to the ArrayList in two places.
First, you put ("code", custcode) to the Map 'datanums' and add it to the List.
Then you put ("name", name) to the same object, i.e. 'datanums'. This means you changed the object which is already contained in the list.
You add this object to the List a second time. Now the List has pairs of identical elements and the ListView shows duplicate entries.
You need only one List element per row, so drop one of the datas.add(datanums); statements.

Related

How to create data for expandable list adapter in a smart way

Experts,
Below code is to get data for ExpandableListAdapter. I have problem about the List temp.
Let say I have below data in db:
Header A, Child 123,111
Header B, child 456,444
Header C, child 789,777
The result I expect is:
expListChild.put(A, 123,111); //(actual result: expListChild.put(A, 123,111,456,444,789,777)
expListChild.put(B, 456,444); //(actual result: expListChild.put(B, 123,111,456,444,789,777)
expListChild.put(C, 789,777); //(actual result: expListChild.put(C, 123,111,456,444,789,777)
I don't know how to do, I've been thought of use temp1, temp2, but I don't know how many rows in Cursor cHeader .
Could you help me please? Thanks.
I guess the problem is I don't know how to create a series of variables.
List<String> expListHeader = new ArrayList<>();
HashMap<String, List<String>> expListChild = new HashMap<>();
List<String> temp = new ArrayList<>();
void xxx() {
Cursor cHeader = db.rawQuery("XXX", null);
cHeader.moveToFirst();
while (cHeader.moveToNext())
{
String headerStr = cHeader.getString(0);
expListHeader.add(headerStr);
Cursor cChild = db.rawQuery("XXX", null);
cChild.moveToFirst();
while (cChild.moveToNext()) {
String childStr = cChild.getString(0);
temp.add(childStr);
}
cChild.close();
expListChild.put(headerStr, temp);
}
}
Put temp.clear() before Cursor cChild = db.rawQuery("XXX", null); to release all objects in your temp list.
Updated (since I was stupid)
List expListHeader = new ArrayList<>();
HashMap> expListChild = new HashMap<>();
void xxx() {
Cursor cHeader = db.rawQuery("XXX", null);
cHeader.moveToFirst();
while (cHeader.moveToNext()) {
String headerStr = cHeader.getString(0);
expListHeader.add(headerStr);
List<String> temp = new ArrayList<>();
Cursor cChild = db.rawQuery("XXX", null);
cChild.moveToFirst();
while (cChild.moveToNext()) {
String childStr = cChild.getString(0);
temp.add(childStr);
}
cChild.close();
expListChild.put(headerStr, temp);
}
}

Listview repeating information

I am trying to do a listview with 2 database collumn. I succeded but my problem is that only the first information of the database appears in the listview. If i have x data in the database it will show the x rows in the listview with only the first entry.
ArrayList<HashMap<String, String>> mylist = new ArrayList<HashMap<String, String>>();
HashMap<String, String> map = new HashMap<String, String>();
data = new ArrayList();
Cursor cursor = mydb.rawQuery("SELECT * FROM projeto", null);
if (cursor.moveToFirst()) {
Toast.makeText(getApplicationContext(), "Caminhos:", 3000).show();
data.clear();
do {
data.add(cursor.getString(cursor.getColumnIndex("id_proj")));
data.add(cursor.getString(cursor.getColumnIndex("nome")));
map.put("id", data.get(0).toString());
map.put("nome", data.get(1).toString());
map.put("hora", "17:00");
mylist.add(map);
} while (cursor.moveToNext());
SimpleAdapter resul = new SimpleAdapter(MainActivity.this, mylist,R.layout.list_item,new String[] {"id", "nome", "hora"}, new int[] {R.id.i, R.id.n, R.id.h});
lista.setAdapter(resul);
I see two problems in your code:
You don't clear data (Like said in a previous answer) so you always get the first two values
You always use the same map. Since map is an object you will always modify the same and your list will be fill will one map.
To fix this two points try this:
ArrayList<HashMap<String, String>> mylist = new ArrayList<HashMap<String, String>>();
data = new ArrayList();
Cursor cursor = mydb.rawQuery("SELECT * FROM projeto", null);
if (cursor.moveToFirst()) {
Toast.makeText(getApplicationContext(), "Caminhos:", 3000).show();
do {
HashMap<String, String> map = new HashMap<String, String>();
data.clear();
data.add(cursor.getString(cursor.getColumnIndex("id_proj")));
data.add(cursor.getString(cursor.getColumnIndex("nome")));
map.put("id", data.get(0).toString());
map.put("nome", data.get(1).toString());
map.put("hora", "17:00");
mylist.add(map);
} while (cursor.moveToNext());
SimpleAdapter resul = new SimpleAdapter(MainActivity.this, mylist,R.layout.list_item,new String[] {"id", "nome", "hora"}, new int[] {R.id.i, R.id.n, R.id.h});
lista.setAdapter(resul);
look at this,
map.put("id", data.get(0).toString());
map.put("nome", data.get(1).toString());
map.put("hora", "17:00");
You always put the same key in the map, always "id, nome and hora" you need put diferent key.
ps: Why you create a List of Map? You don't need to this.
You need to clear data each time through the loop. You need to move your call to data.clear() to just after the do { loop begins. What you're doing at the moment will mean that after the first item is retrieved from the cursor, data will contain 2 items. After the second time it will contain 4, then 6, etc. You then always read the same two items. If you clear data it should fix your problem.

Items from ListView to SQLite, SQLite to ListView

I'm trying to get all the items on my listview (I've attached some image uri) and put them in the database, then get them again and load them on the listview.
What I did is: String hex = array_list.toString(); and put that hex string in the database (sqlite).
FirstFragment:
ListView lv;
ArrayList<Uri> array_list = new ArrayList<Uri>();
ArrayAdapter<Uri> array_adapter;
OnCreate..
array_adapter = new ArrayAdapter<Uri>(getActivity(), android.R.layout.simple_list_item_1, array_list);
lv = (ListView) v.findViewById(R.id.list);
lv.setAdapter(array_adapter);
OnClick..
String hex = array_list.toString();
HashMap<String, String> rcfData = new HashMap<String, String>();
rcfData.put("dateTime", hex);
DataHolder dataHolder = new DataHolder(getActivity());
dataHolder.insertData(rcfData);
Here are the items before I put them in sqlite: (Before clicking OnClick)
SecondFragment:
ListView lv2;
ArrayList<Uri> array_list2 = new ArrayList<Uri>();
ArrayAdapter<Uri> array_adapter2;
OnCreate...
array_adapter2 = new ArrayAdapter<Uri>(getActivity(), android.R.layout.simple_list_item_1, array_list2);
lv2 = (ListView) v.findViewById(R.id.list2);
lv2.setAdapter(array_adapter2);
OnClick...
Intent intent = getActivity().getIntent();
String rcfDataId = intent.getStringExtra("unique_id");
DataHolder dataHolder = new DataHolder(getActivity());
HashMap<String, String> rcfData = dataHolder.get_rcfData(rcfDataId);
if(rcfData.size() !=0) {
String s = rcfData.get("dateTime");
Uri hello = Uri.parse(s);
array_list2.add(hello);
array_adapter2.notifyDataSetChanged();
}
The problem is, when I try to load that string from sqlite to listview of the SecondFragment, it became like this: (After clicking OnClick of SecondFragment)
What I want it to be like (after clicking OnClick of SecondFragment), is like this:
How can I load it like that?
I don't know DataHolder, and I don't know whether it's really backed by an sqlite DB, but this feels like a misuse - you'd probably want to insert each of your items from your ListView as a separate row to your table.
However, if you just want a quick workaround to make it work, you could just split the string you're reading, e.g:
if(rcfData.size() !=0) {
String s = rcfData.get("dateTime");
// Remove brackets
s = s.substring(1, s.length() - 1);
// Split string and insert to ListView
for(String sPart : s.split(", ")) {
Uri hello = Uri.parse(sPart);
array_list2.add(hello);
}
array_adapter2.notifyDataSetChanged();
}

How to get saved value in sqlite database to list in Android?

I am trying to get saved values in a list. I am creating anotepad and I want when anybody open notepad every saved list display on homepage in a list.
I have successfully saved the value in a database but when I am trying to get a value in a list it is giving full string value like this "com.todo.task.activity#4106a690" in every single row.
I think problem is in my database getlist() method please check:
public List<TaskDetailsActivity> GetAddTaskLists() {
List<TaskDetailsActivity> TaskLists = new ArrayList<TaskDetailsActivity>();
// Select All Query
String selectQuery = "SELECT * FROM " + TABLE_TASKLISTS;
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
// looping through all rows and adding to list
if (cursor.moveToFirst()) {
do {
TaskDetailsActivity tasks = new TaskDetailsActivity();
tasks.settaskLists_ID(cursor.getString(0));
tasks.settasklists_Title(cursor.getString(1));
// Adding Doc to list
TaskLists.add(tasks);
} while (cursor.moveToNext());
}
// return Doc list
return TaskLists;
}
Here I am calling database method like this:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ListView list_tasklistname = (ListView)findViewById(R.id.list_tasklistname);
TaskManager_Database db = new TaskManager_Database(getApplicationContext());
list = db.GetAddTaskLists();
ArrayAdapter<TaskDetailsActivity> adapter = new ArrayAdapter<TaskDetailsActivity>(getApplicationContext(),
android.R.layout.simple_list_item_1, list);
list_tasklistname.setAdapter(adapter);
adapter.notifyDataSetChanged();
Please let me know what is the error. Thanks
You are getting object representation of objects been added to ListView...
In your case you should return data in cursor.getString(1) for adapter input param i.e. String array...... i.e list must be a string array or ArrayList... if you know what I mean..
check out this sample for ref
Your TaskDetailsActivity class should define a toString() method that returns whatever you want to display for that row.

All elements are replaced by last element in an arraylist of hashmap

I have values as
Question Q-id
Q1 1
Q2 2
...and so on
I want to retrieve them by calling a function. So i used an arraylist of HashMaps as follows..
public ArrayList<HashMap<String,String>> getAllQuestions(Integer id)
{
try
{
HashMap<String,String> QuesList = new HashMap<String,String>();
ArrayList<HashMap<String, String>> QuestionArrayList = new ArrayList<HashMap<String, String>>();
// Select All Query
String selectQuery = <some query here>;
cursor = mDb.rawQuery(selectQuery, null);
// looping through all rows and adding to list
if (cursor.moveToFirst())
{
do
{
QuesList.put("ques_id", cursor.getString(2));
QuesList.put("ques_text", cursor.getString(8));
QuestionArrayList.add(QuesList);
Log.i("ques",cursor.getString(8) );
} while (cursor.moveToNext());
}
Log.i("check"," Ques list returned");
return QuestionArrayList;
}
catch (SQLException mSQLException)
{
Log.e(TAG, "getTestData >>"+ mSQLException.toString());
throw mSQLException;
}
}
Now the Logcat shows that all questions are retrieved successfully at the time of individual fetch (as shown by the Log.i statement) but whe i run the following loop at the end all the elements are replaced by the last fetched question. Any help is much appreciated.
for(HashMap<String, String> t : QuesList )
{
Log.d("out there", "count" + t.getString());
Log.i("mapping....",t.get("ques_id"));
}
When you call the add method, only the reference to the object is added. So next time you modify the object, the reference refers to the modified object and the old state of the object is not retained.
In your case, you will have to create new objects every time you want to add them to the List:
// looping through all rows and adding to list
if (cursor.moveToFirst())
{
do
{
//Create a new object instance of the Map
HashMap<String,String> QuesList = new HashMap<String,String>();
QuesList.put("ques_id", cursor.getString(2));
QuesList.put("ques_text", cursor.getString(8));
QuestionArrayList.add(QuesList);
Log.i("ques",cursor.getString(8) );
} while (cursor.moveToNext());
}
The reason for this is that, inside your loop, you are only using a single instance of Questlist which is added in the QuestionArrayList.
Try moving
HashMap<String,String> QuesList = new HashMap<String,String>();
inside the loop.
do
{
HashMap<String,String> QuesList = new HashMap<String,String>();
QuesList.put("ques_id", cursor.getString(2));
QuesList.put("ques_text", cursor.getString(8));
QuestionArrayList.add(QuesList);
Log.i("ques",cursor.getString(8) );
} while (cursor.moveToNext());
You don't need a list here, use the map to store all your key/value pairs:
QuesList.put(cursor.getString(2), cursor.getString(8));
Will store your questions in the map. You can then loop:
for(String q : QuesList.values()) {…}
Ps: your problem is that you only use one map and keep using the same key, overriding previous entries.

Categories

Resources