Hey guys i have made a listview of data from my database using simple adapter but i dont know how to update it everytime the database changes.Any help?The notifyDataSetChanged(); method doesnt work and i cant find out what to do.
MainActivity
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_general_discussion);
db = new SQLiteHandler(this);
ArrayList<HashMap<String, String>> emaillist = db.getMessage();
if (emaillist.size() != 0) {
ListAdapter adapter = new SimpleAdapter(MainActivity.this, emaillist,
R.layout.raw_layout,
new String[]{"user_posted", "post", "posted_at", "post_id"}, new int[]{
R.id.text_user_name, R.id.text_user_post, R.id.text_user_date, R.id.text_user_number});
setListAdapter(adapter);
}
HelperClass
public ArrayList<HashMap<String, String>> getMessage(){
ArrayList<HashMap<String, String>> message = new ArrayList<HashMap<String, String>>();
String selectQuery = "SELECT * FROM " + TABLE_POSTING;
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
if ( cursor.moveToFirst()) {
do {
HashMap<String, String> map = new HashMap<String, String>();
map.put("post_id", cursor.getString(0));
map.put("user_posted", cursor.getString(1));
map.put("post", cursor.getString(2));
map.put("posted_at", cursor.getString(3));
message.add(map);
} while (cursor.moveToNext());
}
return message;
}
Declare your adapter & list global level
class example{
ListAdapter adapter;
ArrayList<HashMap<String, String>> emaillist;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_general_discussion);
db = new SQLiteHandler(this);
emaillist = db.getMessage();
if (emaillist.size() != 0) {
adapter = new SimpleAdapter(MainActivity.this, emaillist,
R.layout.raw_layout,
new String[]{"user_posted", "post", "posted_at", "post_id"}, new int[]{
R.id.text_user_name, R.id.text_user_post, R.id.text_user_date, R.id.text_user_number});
setListAdapter(adapter);
}
When you want to update just
adapter.notifyDataSetChanged();
Declare your adapter as Public and just call
adapter.notifyDatasetChange();
when ever wherever you want to. This would update.
Hope this helps.
i don't think there is a direct way to check if something changed in database
but you can make an action like Refresh.
make your adapter as global, when the action is triggered fill the adapter again and write adapter.notifyDatasetChange();
another way is to use Thread, put it into inner class of type AsyncTask
then refill the array every minute
then write adapter.notifyDatasetChange(); after every check like this
doInBackground(){
while(true){
checkDataBase();
refillAdapter();
adapter.notifyDatasetChange();
Thread.sleep(1000*60);// sec * 60 sec =1min
}
}
look at this link how to use AsyncTask class http://developer.android.com/reference/android/os/AsyncTask.html
Related
I have an custom adapter that is giving me problem. When I add or edit something it updates the listview but when I delete it doesn't.
Code when I remove something:
private ArrayList<Teams> m_orders = null;
private TeamsAdapter m_adapter;
private ListView lstv;
...
private void deleteTeam(int indexRemove){
hasKeys.remove(hasKeys.indexOf(m_orders.get(indexRemove).getTeamName()));
Menu.teams.remove(m_orders.get(indexRemove).getTeamName());
m_orders.remove(indexRemove);
m_adapter.notifyDataSetChanged();
}
I tried use a Runnable, but without success.
private Runnable returnRes = new Runnable() {
#Override
public void run() {
if(m_orders != null && m_orders.size() > 0){
m_adapter.notifyDataSetChanged();
for(int i=0;i<m_orders.size();i++)
m_adapter.add(m_orders.get(i));
}
m_adapter.notifyDataSetChanged();
}
};
My onCreate method:
lstv = findViewById(R.id.teamsList);
m_orders = new ArrayList<Teams>();
this.m_adapter = new TeamsAdapter(this, R.layout.row, m_orders);
lstv.setAdapter(this.m_adapter);
You have to remove an item from the ArrayList which is inside the Adapter class. So you need to write your delete function inside the adapter class. In this way will able to delete items and update listview by calling notifyDataSetChanged() method.
You are creating an m_adapter with m_orders dataset, but you are removing item from m_teams dataset, make no sense, they are different instances.
final List<Teams> mTeams = new ArrayList<>();
TeamsAdapter mAdapter;
onCreate() {
mAdapter = new TeamsAdapter(this, R.layout.row, mTeams);
ListView listView = (ListView) findViewById(R.id.teamsList);
listView.setAdapter(mAdapter);
}
addTeams(Collection<Teams> items) {
mTeams.addAll(items);
mAdapter.notifyDataSetChanged();
}
deleteTeam(int index) {
mTeams.remove(index);
mAdapter.notifyDataSetChanged();
}
I want to get the data from getName() method which is in Database class and put those data into ListView.Can anyone please help me out here. It crashes everytime I try to open this activity.
Caused by : java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.util.ArrayList.addAll(java.util.Collection)' on a null object reference"
This is the Error msg that appears when I run below code:
public class ListActivity extends android.app.ListActivity {
ListView mListNames;
ArrayList<String> mNames;
DBForm dbForm = new DBForm(this);`
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list);
mListNames = (ListView) findViewById(android.R.id.list);
mNames.addAll(dbForm.getName());
this.setListAdapter(new ArrayAdapter<>(this, R.layout.list_head, mNames));
}
}
And this how I store and Retrieve the data inside DB class:
public ArrayList<String> getName() {
ArrayList<String> array_list = new ArrayList<>();
SQLiteDatabase db = this.getReadableDatabase();
Cursor res = db.rawQuery("select name from contacts" , null);
res.moveToFirst();
while (!res.isAfterLast()) {
array_list.add(res.getString(res.getColumnIndex(CONTACTS_COLUMN_NAME)));
res.moveToNext();
}
res.close();
return array_list;
}
Your problem in getName() method. Maybe your table is empty. You need to check null of your cursor before loop it. Like below:
if (cursor.moveToFirst()) {
while (cursor.isAfterLast() == false) {
String name = cursor.getString(cursor.getColumnIndex(countyname));
list.add(name);
cursor.moveToNext();
}
}
Refer to: Get all rows from SQLite
So I made a silly mistake here in defining the target XML file.I choose one layout file and instead of choosing the textView id from the same layout file I accidently put another layout files textView id.
adapter = new ArrayAdapter<>(this, R.layout.list_view, R.id.list_names, mNames);
mListNames.setAdapter(adapter);
I'm aware that this is very simple question but I'm a newbie in Android development so please go easy on me.
Problem that I have is in one of the fragments (AsyncTask specifically) that lays in my main activity.
AsyncTask sends out data to php script which then returns according data in json format. This is then processed and saved to jsonlist array. Up until post execute everything works fine data is downloaded, processed etc. However when program reaches post execute problems start to pop out. And basically i'm unable to list out all the data from jsonlist to listview
//setting up an array
ArrayList<HashMap<String, String>> jsonlist = new ArrayList<HashMap<String, String>>();
//creating list view variable
ListView listview;
//Define work in progress dialog
private ProgressDialog mProgressDialog;
private class ProgressTask extends AsyncTask<String, Void, Boolean> {
#Override
protected void onPreExecute() {
super.onPreExecute();
// Create a progressdialog
mProgressDialog = new ProgressDialog(getActivity());
// Set progressdialog title
mProgressDialog.setTitle("Please wait");
// Set progressdialog message
mProgressDialog.setMessage("Fetching data...");
mProgressDialog.setIndeterminate(false);
}
#Override
protected Boolean doInBackground(String... params) {
//To do in the background
//Define variable of JSON parser type
JSONParser jParser = new JSONParser();
//Pass url to json parser class to fetch and save it into array variable
JSONArray json = jParser.getJSONFromUrl(url);
//loop from 0 to length of an array by increasing by 1
for (int i = 0; i < json.length(); i++) {
//Try and catch routine to prevent any crashes
try {
//Get an object defined in { ... } in original json file
JSONObject c = json.getJSONObject(i);
//Separate object by obtaining values for each of the sections
String vtitle = c.getString(title);
String vcontent = c.getString(content);
String vuser = c.getString(user);
HashMap<String, String> map = new HashMap<String, String>();
//Fill up an array with data extracted
map.put(title, vtitle);
map.put(content, vcontent);
map.put(user, vuser);
//Add values into jsonlist
jsonlist.add(map);
} catch (JSONException e)
{
//In case of any error Stack trace will be returned
e.printStackTrace();
}
}
//Once everything has been done return null value
return null;
}
#Override
protected void onPostExecute(Boolean aBoolean) {
//Insert all data downloaded through list adapter
ListAdapter adapter = new SimpleAdapter(getActivity(), jsonlist, R.layout.list_activity, new String[] { title, content, user }, new int[] { R.id.title, R.id.content, R.id.user });
// Locate the listview
//listview = (ListView) findViewById(R.id.list);
// Set the adapter to the ListView
//listview.setAdapter(adapter);
//Get rid off dialog when operation of fetching data has been done
if (mProgressDialog.isShowing()) {
mProgressDialog.dismiss();
}
}
}
As you can see i have tried the commented code but listview = (ListView) findViewById(R.id.list); returns following error:
Cannot resolve method findViewById(int)
which prevents me from executing program. This is very upsetting because I literally have all the data i need in an array but only one line of code stops me from displaying it.
I have also tried:
ListAdapter adapter = new SimpleAdapter(context, jsonlist, R.layout.list_activity, new String[] { title, content, user }, new int[] { R.id.title, R.id.content, R.id.user });
setListAdapter(adapter);
lv = getListView();
But as in previous case error of unresolved method is returned. Which is due to the fact that fragment is extended by fragment and adding anything to it crashes it
public class Fragment2 extends Fragment, ListActivity {...}
Add this to your code in Fragment2 class.
private ListView listview;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.YOUR_FRAGMENT_LAYOUT, container, false);
listview = (ListView) v.findViewById(R.id.R.id.list);
return v;
}
Since you are in a Fragment you have to call getView() before findViewById, like this
//Insert all data downloaded through list adapter
ListAdapter adapter = new SimpleAdapter(getActivity(), jsonlist, R.layout.list_activity, new String[] { title, content, user }, new int[] { R.id.title, R.id.content, R.id.user });
// Locate the listview
listview = (ListView) getView().findViewById(R.id.list);
I was looking at this code while surfing through Stackoverflow
CODE::
public class MainActivity extends Activity {
// Declare Variables
JSONObject jsonobject;
JSONArray jsonarray;
ListView listview;
ListViewAdapter adapter;
ProgressDialog mProgressDialog;
ArrayList<HashMap<String, String>> arraylist;
static String NAME = "rank";
static String TYPE = "country";
static String DISTANCE = "distance";
static String RATING = "rating";
static String FLAG = "flag";
static String PRICE= "price";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Get the view from listview_main.xml
setContentView(R.layout.listview_main);
// Locate the listview in listview_main.xml
listview = (ListView) findViewById(R.id.listview);
// Execute DownloadJSON AsyncTask
new DownloadJSON().execute();
}
// DownloadJSON AsyncTask
private class DownloadJSON extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
// Create a progressdialog
mProgressDialog = new ProgressDialog(MainActivity.this);
// Set progressdialog title
//mProgressDialog.setTitle("Fetching the information");
// Set progressdialog message
mProgressDialog.setMessage("Loading...");
mProgressDialog.setIndeterminate(false);
// Show progressdialog
mProgressDialog.show();
}
#Override
protected Void doInBackground(Void... params) {
// Create an array
arraylist = new ArrayList<HashMap<String, String>>();
// Retrieve JSON Objects from the given URL address
jsonobject = JSONfunctions.getJSONfromURL("--------------URL----------");
try {
// Locate the array name in JSON
jsonarray = jsonobject.getJSONArray("ARRAY");
for (int i = 0; i < jsonarray.length(); i++) {
HashMap<String, String> map = new HashMap<String, String>();
jsonobject = jsonarray.getJSONObject(i);
// Retrive JSON Objects
map.put(MainActivity.NAME, jsonobject.getString("collegeNAME"));
map.put(MainActivity.TYPE, jsonobject.getString("collegeTYPE"));
map.put(MainActivity.FLAG, jsonobject.getString("collegeIMAGE"));
map.put(MainActivity.DISTANCE, jsonobject.getString("collegeDISTANCE"));
map.put(MainActivity.RATING, jsonobject.getString("collegeRATING"));
map.put(MainActivity.PRICE, jsonobject.getString("collegePrice"));
// Set the JSON Objects into the array
arraylist.add(map);
}
} catch (JSONException e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void args) {
// Pass the results into ListViewAdapter.java
adapter = new ListViewAdapter(MainActivity.this, arraylist);
// Set the adapter to the ListView
listview.setAdapter(adapter);
// Close the progressdialog
mProgressDialog.dismiss();
}
}
}
My Question is Why we use collection in android ?
What is the use ?
Why a hashmap is added to ArrayList in the above code ?
Can't we directly set views in android without collection,( I tried
it dosent work when dealing with group of key,value pairs)
.
~ I am a newbie so please go easy on with answers to my questions
I'm not sure how to answer your first 2 questions about collections... but I'll give it a shot.
1, 2) Collections are good for keeping groups of information lumped together and accessible through 1 variable. They also make it very easy to iterate over them, which makes them ideal for things like ListView adapters since that is also a list (or a collection).
Consider the following if you dont have an array
String var1 = "hi1";
String var2 = "hi2";
String var3 = "hi3";
String var4 = "hi4";
String var5 = "hi5";
String var6 = "hi6";
String var7 = "hi7";
String var8 = "hi8";
String var9 = "hi9";
// do something with the variables
Toast.makeText(this, var1, Toast.LENGTH_SHORT).show();
Toast.makeText(this, var2, Toast.LENGTH_SHORT).show();
Toast.makeText(this, var3, Toast.LENGTH_SHORT).show();
Toast.makeText(this, var4, Toast.LENGTH_SHORT).show();
Toast.makeText(this, var5, Toast.LENGTH_SHORT).show();
Toast.makeText(this, var6, Toast.LENGTH_SHORT).show();
Toast.makeText(this, var7, Toast.LENGTH_SHORT).show();
Toast.makeText(this, var8, Toast.LENGTH_SHORT).show();
Toast.makeText(this, var9, Toast.LENGTH_SHORT).show();
Now consider this, if you have arrays:
ArrayList<String> vars = new ArrayList<String(9);
for (int i = 1; i <= 9; i++)
{
vars.add("hi" + i);
Toast.makeText(this, vars.get(i), Toast.LENGTH_SHORT).show();
}
Much, much easier to work with.
3) The Hashmap is added to the array because the author wanted to keep a collection of separate name/value pairs. You can't have multiple keys with the same value in a Hashmap, so if you want that then you have to make a new Hashmap. The adding them to an array was to keep it neat, and then allowed the author to pass the array to a ListView adapter for displaying the values to the user using Android's built-in mechanism.
Basically the author created this Hierarchy:
item1
name
type
flag
distance
rating
price
item2
name
type
flag
distance
rating
price
item3
name
type
flag
distance
rating
price
...etc...
So when the ListView iterated over the array, each separate collection of hashmap values will be available to a new listview item for displaying.
4) You can set values directly, but working with adapters in ListViews makes it much less of a chore. You create an array, pass the array to the listview, and bada-bing-bada-boom, there's your list. Otherwise you will be creating ListView items and setting the display text all yourself for each item. In a similar way to why collections are useful when you have many variables of the same type, passing that collection to a ListView makes it much, much easier to code, maintain, and troubleshoot, not to mention that it just works!
I hope this helps! We are all beginners once :)
This piece of code will go populate an ListView, there are several ways to do that. I believe in this case, the coder is SimpleAdapter http://developer.android.com/reference/android/widget/SimpleAdapter.html.
Some think like:
// In This case the value os NAME is shown on android.R.id.text1 (TextView)
// and PRICE is shown on android.R.id.text2 (TextView)
String[] from = new String[]{MainActivity.NAME, MainActivity.PRICE}; // Map keys
int[] to = new int[]{android.R.id.text1, android.R.id.text2}; // List Layout item views
SimpleAdapter adapter = new SimpleAdapter(context, arraylist, android.R.layout.simple_list_item_2, String[] from, int[] to);
listview.setAdapter(adapter);
I am trying to display my list of alarms in the ListActivity but it does not work. There rows appear but there is no text visible. I'm not sure if it's retrieving the data from the HashMap and inserting into the rows correctly.
Here is my code:
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_alarm_list);
List<Alarm> list;
Database db = new Database(AlarmListActivity.this);
list = db.getAllAlarms();
List<HashMap<String, String>> alarmMap = new ArrayList<HashMap<String, String>>();
for (Alarm alarm: list) {
HashMap<String, String> map = new HashMap<String, String>();
map.put(Integer.toString(alarm.getID()), alarm.toString());
alarmMap.add(map);
}
if(!list.isEmpty() && list != null)
{
System.out.println("inside list");
System.out.println(list);
ListAdapter adapter = new SimpleAdapter(
AlarmListActivity.this,
alarmMap,
R.layout.list_item,
new String[] { "id", "hour"},
new int[] { R.id.id, R.id.time});
setListAdapter(adapter);
}
else
{
Toast.makeText(AlarmListActivity.this, "No Alarms Set",
Toast.LENGTH_SHORT).show();
}
}
This is what I get. You can vaguely see the lines of each row. But there is no text or anything. All the System.out.println() work as expected which print out the HashMap. It's just nothing is being displayed in the list. I've even added: android:text="Testing" to no avail