How to dynamic update the adapter for activities? - java

I am working on an app which combines the SQL and the adapter. The main issue is that once I updated the database, the adapter will not reflect my update directly. Here's the code:
public class RSSItemActivity extends ListActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.rssitem);
long channelid = getIntent().getExtras().getLong(RSSReaderApp.CHANNEL_KEY);
DBAdaptor dbAdaptor = ((RSSReaderApp)getApplication()).getDBAdaptor();
Cursor cursor = dbAdaptor.getRssItems(channelid);
adapter = new RSSItemAdapter(this, R.layout.rssitemview, cursor);
setListAdapter(adapter);
}
As you can see, this code get the data from the SQL at the line Cursor cursor = dbAdaptor.getRssItems(channelid);(The get RssItems is just loading data we want to present on the screen from the SQL). However, I have some bottoms in the same activity that if I press that, it will change the values in the SQL, which should affect the data it retrieve. (For example, there's a column decide what's these item's color, it is originally set to white, after I press that, it should be blue.) However, once I press that, seems although the data in the SQL is changed, but the real presentation is still the same color. I had tried using adapter.swapCursor(dbAdapter.getRssItems(id)); on the bottom to update the cursor everytime I press the buttom, but it will let my original display disappear (Possibly because the original adapter loses it's cursor,so it can display nothing), I have to reload that page to get the correct output. Is there a way that I can instantly update the output? Thanks for your reply in advance =)

You will have to update the cursor in the adapter. You could call the following:
// Closes the old cursor as well.
adapter.changeCursor(dbAdapter.getRssItems(id));
// Notify the view that the underlying data has changed.
adapter.notifyDataSetChanged();
Also, the difference with swapCursor() is that changeCursor, automatically closes the old cursor, while swapCursor does not.

try this...
runOnUiThread(returnResult);
private Runnable returnResult = new Runnable() {
#Override
public void run() {
if(array_list.size() > 0)
{
m_adapter.notifyDataSetChanged();
for(int i=0;i<array_list.size();i++)
m_adapter.add(array_list.get(i));
}
m_adapter.notifyDataSetChanged();
}
};

Related

When press back button listview going top. How to fix that?

In my codes there is two fragment. List page and detail page. There is lot of alphabetic item on list page. And when i clicked some item opening the detail page. But when i press back button, the list doesn't stay same position. It goes to the top. I searched some solution but i think that's not common issue. I couldn't find different answers. Is there anyone to help me?
At first glance, it looks like it's one of your calls to: dictionaryFragment.resetDatasource(source);
Which is resetting the Adapter on your ListView to a brand new ArrayAdapter. This will reset the ListView to the top because the adapter is an entirely new object. The ListView no longer has any idea about the old ArrayAdapter and thus resets to the top.
public void resetDatasource (ArrayList<String> source){
mSource=source;
adapter = new ArrayAdapter<String>(getContext(),R.layout.kelimelistesi, mSource);
dicList.setAdapter(adapter);
}
Rather than calling
adapter = new ArrayAdapter<String>(getContext(),R.layout.kelimelistesi, mSource);
dicList.setAdapter(adapter);
You should do more like this:
public class DictionaryFragment ... {
private Adapter mAdapter;
public View onCreateView(...) {
// Init the layout here
// Put some other ArrayList here if you have one initially, else an empty one to start
mAdapter = new ArrayAdapter<String>(getContext(), R.layout.kelimelistesi, new ArrayList<String>());
dicList.setAdapter(mAdapter);
}
public void resetDatasource(ArrayList<String> source) {
mAdapter.clear();
mAdapter.addAll(source);
mAdapter.notifyDataSetChanged();
}
...
}
This difference now is that the same mAdapter instance is bound to dicList the whole time, but only the underlying data to display changed. Think of a ListView/RecyclerView's Adapter as a class that takes some input data and binds it to some UI elements. In this case, each String in the ArrayAdapter is displayed in some UI element like a TextView or what not.
ALSO important: note that we call notifyDataSetChanged() AFTER we have cleared the old data and added all the new data. This will help avoid flickering and scrolling issues from trying to elements one at a time.

Getting a button to work in the list view

I am new to android and my code has got a bit messy. I have successfully created a list view extended from item_layout.xml. When I click on the list view It works exactly how I want it. However in each item of the list view I have a button that when clicked I want the item of the list to delete.
When researching I have come across that you need to create a customer adapter to do this however I have come so far in the project that I wouldn't even know where to start.
This code it used successfully to when the list items are clicked it works. This is just put in the Main Activity class
mylist.setOnItemClickListener(
new AdapterView.OnItemClickListener(){
#Override
public void onItemClick(AdapterView<?> parent, View view, final int position, long id) {
}
}
);
I populate the list using this function just outside the main activity class. It is needed to be written like this as It gets the items from a database and has to be called depending on different circumstances
private void populatelistView() {
Cursor res = userDb.getAllRows();
String[] fromFeildnames = new String[]{ DatabaseUser.KEY_1, DatabaseUser.KEY_2};
int[] toViewIds = new int[]{R.id.textViewNum, R.id.textViewItem};
SimpleCursorAdapter myCursorAdaptor;
myCursorAdaptor = new SimpleCursorAdapter(getBaseContext(), R.layout.item_layout, res, fromFeildnames, toViewIds, 0);
//ListView mylist = (ListView) findViewById(R.id.listViewID);
mylist.setAdapter(myCursorAdaptor);
}
I would like to be able to get the button on each items to work by not changing much of what I have already written. I have tried just using the following code. But because it is in a different xml layout it display an error of null reference towards the item button
delete.setOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View v) {
View parentRow = (View) v.getParent();
ListView listView = (ListView) parentRow.getParent();
final int position = listView.getPositionForView(parentRow);
Toast.makeText(getApplicationContext(), "Button " + position, Toast.LENGTH_SHORT).show();
}
}
);
Please could someone help me make the button work without changing much code or give me a step by step tutorial on how to add an adapter but make my populateListView function do the same thing.
Ps. I have looked at so many tutorials about list adapters but can't find ones that are for my specific need

onListItemClick add item to ListView in another activity

I am very sorry if this question already exists, but I couldn't find any answer to my problem. The idea of my application is a Shopping List. The user can see a list of food and on clicking on an item, it should automatically be added to a list.
What I already have is a ListView generated from an xml-file in a raw folder. This is my food, I haven't stored it in a SQLite Database.
What I want to do now is that when I click on an item in this list, it's added to a ListView in another Activity called "ShoppingList.java". It shouldn't open immediately, so the user has the possibility to add more items.
Now, when I click on an item, it's added to a TextView called "selection" in the same Activity on the top of the screen.
How is it possible to add an item from one Activity to another one?
Thank you very much for your help!
public class FishOk extends ListActivity {
TextView selection;
ArrayList<String> items=new ArrayList<String>();
#Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.foodok_list);
selection=(TextView)findViewById(R.id.selection);
try {
InputStream in=getResources().openRawResource(R.raw.fish);
DocumentBuilder builder=DocumentBuilderFactory
.newInstance()
.newDocumentBuilder();
Document doc=builder.parse(in, null);
NodeList words=doc.getElementsByTagName("product");
for (int i=0;i<words.getLength();i++) {
items.add(((Element)words.item(i)).getAttribute("value"));
}
in.close();
}
catch (Throwable t) {
Toast
.makeText(this, "Exception: "+t.toString(), 2000)
.show();
}
ListView lstView = getListView();
lstView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
lstView.setTextFilterEnabled(true);
setListAdapter(new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1,
items));
}
public void onListItemClick(ListView parent, View v, int position,
long id) {
selection.setText(items.get(position).toString());
}
public void onClick(View view) {
ListView lstView = getListView();
String itemsSelected = "Selected items: \n";
for (int i=0; i<lstView.getCount(); i++) {
if (lstView.isItemChecked(i)) {
itemsSelected += lstView.getItemAtPosition(i) + "\n";
}
}
Toast.makeText(this, itemsSelected, Toast.LENGTH_LONG).show();
}
Adding an item to the ListView of an Activity which isn't visible to the user and doesn't yet exist makes no sense. You should have a place where you'll store the data, it can be a SQLite database, a plain text file, or SharedPreferences if there's not much data. When you're clicking on a Button inside your current Activity you should store the information to your data storage, and then retrieve it to populate the ListView when the second Activity starts. Hope this helps.
Activity is a window where you can put your UI stuff so that user can interact with the application.
Now, for using the data in the activities across the application, you have to use either Collections or Database.
But as per your requirement, I think you should use Collections.
Maintain an Arraylist or a HashTable according to your data.
Pass that data from one activity to other.
OR
Maintain a singleton class and update the data in that class. Access the data from other activities.
I hope this helps you.

Add the contents of a database to a ListView via a Cursor

So I'm gunna try give as much information as I can to get this sorted. My application contains a database with the standard methods implemented; retrieving a record or all records returns a Cursor.
My application has a ListView, a text box and an add button. Here's what I'm trying to achieve (please note, the first is the most important):
I would like to display the current contents of the database in the ListView area.
I want to have the button insert whatever is in the text box into the database (and the ListView should automatically update to show the insertion)
I would like the ability to tap an item in the ListView and have it deleted from the database.
I have tried to tackle the first bullet point through assigning a Cursor to the return of the getAllRecords() method; Cursor c = dba.getAllRecords();. I have tired to get it to add field entries via a for-loop which didn't turn out too well.
Button add;
EditText tm;
ListView lv;
DBAdapter dba = new DBAdapter(this);
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_general);
add = (Button) findViewById(R.id.button1);
tm = (EditText) findViewById(R.id.editText1);
lv = (ListView) findViewById(R.id.generalList);
Cursor c = dba.getAllRecords();
c.moveToFirst();
// Trying to add database contents to ListView here.
add.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
insertIntoDatabase();
}
});
}
If you have a Cursor from a database and whant to show into a list, and is simple data like a few text values. Take a look at SimpleCursorAdapter.
The situation is this, you need an adapter, the adapter is the one that loads from the cursor and push into the layout that represent the correspoding list item. Anything that inherits from a CursorAdapter is good. All depends on how much flexibility you need, so you may implement as much as you need.
This is a snnipet from a sample app that I posted at github.
https://github.com/soynerdito/trainningSample/blob/master/src/com/example/sample/app/Dashboard.java
Also the app is in the marketplace. Is just a very simple app used during a "trainning" the app is called "Nerdito Sample" search for it, try and the code is on github. Adds items to a database and show in list.
Sample:
Device device = new Device();
Cursor cursor = mdb.get(device);
SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,
android.R.layout.simple_list_item_2, cursor, new String[] {
device.mDescription.mName, device.mDeviceID.mName },
new int[] { android.R.id.text1, android.R.id.text2 }, 0);
// Create Cursor and set to List
mDeviceListView.setAdapter(adapter);

How to switch activity with item specific data sent

I've had a look around, and it might be because I'm not sure what I'm looking for, but I can't find out how to do something I presume should be quite easy with android.
I have an array of data to display on the screen. This data is a class that holds a database key, name and image.
I'm currently displaying this data as an ImageView and a TextView. I loop through the array and add a new row to a TableLayout containing the image and text.
I'd like both the image and text to be clickable, changing to a new activity.
This new activity needs to know the database key of the row clicked in order to display the correct data.
Here's what I have so far:
private void fillSuggestionTable(TableLayout tabSuggestions, Suggestion[] arrToAdd)
{
for(int i = 0; i < arrToAdd.length; i++)
{
/* Create a new row to be added. */
TableRow trSuggestion = new TableRow(this);
trSuggestion.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.WRAP_CONTENT));
/* Create objects for the row-content. */
ImageView imgDisplayPicture = new ImageView(this);
ImageHandler.loadBitmap(arrToAdd[i].strImageURL, imgDisplayPicture);
imgDisplayPicture.setLayoutParams(new LayoutParams(50,50));
TextView txtArtistName = new TextView(this);
txtArtistName.setText(arrToAdd[i].strName);
txtArtistName.setTextColor(Color.parseColor("#000000"));
/* Add data to row. */
trSuggestion.addView(imgDisplayPicture);
trSuggestion.addView(txtArtistName);
/* Add row to TableLayout. */
tabSuggestions.addView(trSuggestion, new TableLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
}
}
Is there a reason you're using a TableView? it seems like what you want to accomplish would be much easier with a ListView & custom CursorAdapter, where the adapter can handle translating from the database to the ListView row. At that point starting a new activity that knows the database ID is trivial:
mListView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick (AdapterView<?> parent, View view, int position, long id) {
Intent i = new Intent(MyActivity.this, MyOtherActivity.class);
i.putExtra("database_id", id);
startActivity(i);
}
});
And in MyOtherActivity:
private int dbId;
protected void onCreate(Bundle savedInstanceState) {
//do stuff
dbId = getIntent().getIntExtra("database_id", -1); // the -1 is the default if the extra can't be found
}
To pass extra data to another Activity, you need to add extra information with the Intent.putExtra(name, value) methods.
For example, to send the Intent:
Intent i = new Intent([pass info about next Activity here]);
i.putExtra("databaseKey", databaseKey);
startActivity(i);
To get the data out again:
public void onCreate(Bundle savedInstance)
{
// Do all initial setup here
Bundle extras = getIntent().getExtras();
if (extras != null && extras.containsKey("databaseKey"))
{
int databaseKey = extras.getInt("databaseKey");
// Load database info
}
else
{
// No data was passed, do something else
}
}
EDIT: To find out when the table's row is clicked, you'll need to implement View.OnClickListener and set the onClickListener for the TableRows you use.
For example:
/* Create a new row to be added. */
TableRow trSuggestion = new TableRow(this);
trSuggestion.setOnClickListener([listener]);
The only problem you'll have is relating a View's ID to the related database row ID. A HashMap should help.
This is a pretty simple procedure. This blog explains it in simple terms.

Categories

Resources