I have an application where the user will click on an item in the listview and either save, cancel, or delete the entry(this is done on a new activity that is started on the item click). so in the activity that is started on item click , after i click either button i call finish() to return to my previous activity and in this case the activity with the listview. However, if I do any change to the item in the list, the list is not changed at all. I tried using both .notifyDataSetChanged() and invalidateViews but neither of the two worked. Here is my code.
public class Flashcards_List extends ListActivity{
String[] All_Cards = null;
ArrayAdapter<String> adapter;
ListView listview;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.flashcards_list);
Flashcards Cards = new Flashcards(this);
Cards.open();
All_Cards = Cards.getAllFronts();
listview = (ListView) findViewById(android.R.id.list);
listview.invalidateViews();
adapter = new ArrayAdapter<String>(Flashcards_List.this, android.R.layout.simple_list_item_1, All_Cards);
// Assign adapter to ListView
listview.setAdapter(adapter);
}
#Override
protected void onListItemClick(ListView l, View v, int position, long id) {
// TODO Auto-generated method stub
super.onListItemClick(l, v, position, id);
String Specific_Card = All_Cards[position];
/* Class to assist us in loading the activity */
Class editClass = null;
try {
editClass = Class.forName("com.example.flashcards.Edit_Flashcard");
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Bundle specificCard = new Bundle();
specificCard.putString("card", Specific_Card);
Intent ourIntent = new Intent(Flashcards_List.this, editClass);
ourIntent.putExtras(specificCard);//passing the bundle to the activity
startActivity(ourIntent);
adapter.notifyDataSetChanged();
}
}
This class edits the DB entry
public class Edit_Flashcard extends Activity implements OnClickListener{
String front_of_card = null;
Bundle bundle_received;
Button cancel, delete, save;
EditText front, back;
String[] card;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.edit_flashcard);
bundle_received = getIntent().getExtras();
front_of_card = bundle_received.getString("card");//current card is the card that was clicked on
Flashcards info = new Flashcards(this);
info.open();
card = info.getCard(front_of_card);
info.close();
initialize();
}
public void initialize(){
front = (EditText) findViewById(R.id.front);
back = (EditText) findViewById(R.id.back);
front.setText(card[1]);
back.setText(card[2]);
cancel = (Button) findViewById(R.id.cancel);
save = (Button) findViewById(R.id.save);
delete = (Button) findViewById(R.id.delete);
cancel.setOnClickListener(this);
save.setOnClickListener(this);
delete.setOnClickListener(this);
}
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch(v.getId()) {
case R.id.cancel:
super.finish();//finishes the activity, and returns to previous Activity
break;
case R.id.save:
try{
Flashcards update_entry = new Flashcards(this);
update_entry.open();
update_entry.updateEntry(card[0], front.getText().toString(), back.getText().toString());
update_entry.close();
}catch(Exception e){
String save_text = "The Flashcard could not be saved. Please try again.";
int duration = Toast.LENGTH_SHORT;
Toast toast = Toast.makeText(Edit_Flashcard.this, save_text, duration);
toast.setGravity(Gravity.CENTER_VERTICAL, 0, 0);
toast.show();
}
super.finish();
break;
case R.id.delete:
try{
Flashcards delete_entry = new Flashcards(this);
delete_entry.open();
delete_entry.deleteEntry(card[0]);
delete_entry.close();
}catch(Exception e){
/* set the value to NOT INSERTED */
String delete_text = "The Flashcard could not be deleted. Please try again.";
int duration = Toast.LENGTH_SHORT;
Toast toast = Toast.makeText(Edit_Flashcard.this, delete_text, duration);
toast.setGravity(Gravity.CENTER_VERTICAL, 0, 0);
toast.show();
}
super.finish();
break;
}/* end Switch */
}/* end onClick */
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/background"
android:orientation="vertical" >
<ListView
android:id="#android:id/list"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
</LinearLayout>
Launch EditClass activity by startActivityForResult method. Implement onActivityResult method in the calling activity and in that method call adapter.notifyDatasetChanged.
Intent ourIntent = new Intent(Flashcards_List.this, editClass);
ourIntent.putExtras(specificCard);//passing the bundle to the activity
startActivity(ourIntent);
adapter.notifyDataSetChanged();
notifyDataSetChanged is executed IMMEDIATELY after you call startActivity(), it doesn't block. Instead, you should load your data in onResume(), that way the latest data will always be shown when the activity comes back. Basically leave only the setContentView() in your onCreate.
Related
I am trying to pass a value on my ListView to my second activity using Intents. I am not sure how to pass the text value to the second activity my Intent leads to. Right now my Intent is able to connect to the second activity on tap but it doesn't pass the string of the tapped value.
I feel that I need to pass something into my launchEditItem() but I am not sure what. These are the two functions I am dealing with right now.
private void launchEditItem() {
Intent i = new Intent(this, EditItemActivity.class);
i.putExtra("itemOnList", ); // list item into edit text
startActivity(i);
}
private void setupEditItemListener() { // on click, run this function to display edit page
lvItems.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> adapter, View item, int pos, long id) {
launchEditItem();
}
});
}
I'm not sure what value to place into the i.putExtra(), but I think I need to pass an argument into the launchEditItem().
This is what is currently in my second Activity:
public class EditItemActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_edit_item);
Intent i = getIntent();
String ItemToEdit = i.getStringExtra("itemOnList");
// place into EditText using ItemToEdit
}
I'm also not sure how to place this String value (ItemToEdit) into an EditText box. I'm new to android dev so I'm learning as much as I can thank you!
* EDIT *
I guess I'm a bit too vague in my question. Here is the entire code of the small app I am working on
public class ToDoActivity extends Activity {
private ArrayList<String> todoItems;
private ArrayAdapter<String> todoAdapter; // declare array adapter which will translate the piece of data to teh view
private ListView lvItems; // attach to list view
private EditText etNewItem;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_to_do);
etNewItem = (EditText) findViewById(R.id.etNewItem);
lvItems = (ListView) findViewById(R.id.lvItems); // now we have access to ListView
//populateArrayItems(); // call function
readItems(); // read items from file
todoAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, todoItems); //create adapter
lvItems.setAdapter(todoAdapter); // populate listview using the adapter
//todoAdapter.add("item 4");
setupListViewListener();
setupEditItemListener();
}
private void launchEditItem() {
Intent i = new Intent(this, EditItemActivity.class);
i.putExtra("itemOnList", ); // list item into edit text
startActivity(i);
}
private void setupEditItemListener() { // on click, run this function to display edit page
lvItems.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> adapter, View item, int pos, long id) {
launchEditItem();
}
});
}
private void setupListViewListener() {
lvItems.setOnItemLongClickListener(new OnItemLongClickListener() {
#Override
public boolean onItemLongClick(AdapterView<?> adapter, View item, int pos, long id) {
todoItems.remove(pos);
todoAdapter.notifyDataSetChanged(); // has adapter look back at the array list and refresh it's data and repopulate the view
writeItems();
return true;
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.to_do, menu);
return true;
}
public void onAddedItem(View v) {
String itemText = etNewItem.getText().toString();
todoAdapter.add(itemText); // add to adapter
etNewItem.setText(""); //clear edit text
writeItems(); //each time to add item, you want to write to file to memorize
}
private void readItems() {
File filesDir = getFilesDir(); //return path where files can be created for android
File todoFile = new File(filesDir, "todo.txt");
try {
todoItems = new ArrayList<String>(FileUtils.readLines(todoFile)); //populate with read
}catch (IOException e) { // if files doesn't exist
todoItems = new ArrayList<String>();
}
}
private void writeItems() {
File filesDir = getFilesDir(); //return path where files can be created for android
File todoFile = new File(filesDir, "todo.txt");
try {
FileUtils.writeLines(todoFile, todoItems); // pass todoItems to todoFile
} catch (IOException e) {
e.printStackTrace();
}
}
}
String[] link_list;
int currenttrack=0;
link_list=new String[]{
"W-TE_Ys4iwM",//1
"oozgmH3ZP14",//2
"o_v9MY_FMcw",//3
"36mCEZzzQ3o",//4
}
First activity
list.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
// TODO Auto-generated method stub
currenttrack=arg2;
Intent videoIntent=new Intent(MainActivity.this,VideoView.class);
videoIntent.putExtra("filename", link_list[currenttrack]);
startActivity(videoIntent);
}
});
In your Second Activity
// getting intent data
// get intent data
Intent i = getIntent();
Bundle extras = i.getExtras();
filename = extras.getString("filename");
Log.e("File Name", filename);
and your done :)
In your current Activity, create a new Intent:
Intent i = new Intent(getApplicationContext(), NewActivity.class);
i.putExtra("new_variable_name","value");
startActivity(i);
Then in the new Activity, retrieve those values:
Bundle extras = getIntent().getExtras();
if (extras != null) {
String value = extras.getString("new_variable_name");
}
I am not sure if i understood where is the value. Well if the value is in EditText do something like:
private void launchEditItem(String text) {
Intent i = new Intent(this, EditItemActivity.class);
i.putExtra("itemOnList", text); // list item into edit text
startActivity(i);
}
private void setupEditItemListener() { // on click, run this function to display edit page
lvItems.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> adapter, View item, int pos, long id) {
EditText editView = (EditText) item.findById(R.id.ItemToEdit);
String text = editView != null ? editView.getText().toString() : "";
launchEditItem(text);
}
});
}
1 - I have some doubt with:
i.putExtra("itemOnList", );
You'd better pass a value:
i.putExtra("itemOnList", "something");
2 - To valorize a control, you must obtain a reference to it first. Something like:
EditText edt =
(EditText) findViewById(R.id.activity_edit_item_my_EditText); // or whatever id you assigned to it (it MUST HAVE AN ID)
Do it AFTER setContentView().
Then you can set it's text like:
edt.setText(ItemToEdit); // Now it should contain "something"
Just as simple as that
[EDIT]
If you aren't sure what to pass so is to pass in the "tapped" value in the ListView into the putExtra, modify your listview click handler code:
list.setOnItemClickListener
(
new OnItemClickListener()
{
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3)
{
// TODO Auto-generated method stub
Intent videoIntent = new Intent(MainActivity.this, VideoView.class);
videoIntent.putExtra("filename", (((TextView) v).getText().toString());
startActivity(videoIntent);
}
}
);
It should work immediately.
01: Current Activity
String pass_value ="value";
Intent intent = new Intent(getApplicationContext(),NewActivity.class);
intent.putExtra("var_name",pass_value);
startActivity(intent);
02: New Activity
String value = getIntent().getExtras().getString("var_name");
I'm wondering if there is some trick to get the spinner updated from an edittext and onClick, before it gets committed to the database and retrieve from there? The list and the spinnerAdapter are set for retrieving values from database, so I'm aware that this question might be stupid.
I was thinking of this logic: enter some text to edittext, click ok, then temporary update the spinner with this text, before it goes to database, then do some other stuff in the activity and last commit everything to database. When you then close and open your activity again, the temporary value is lost, but the spinner gets populatet with the same value, but this time from database.
here is some code:
public class Vnos extends Activity {
//... some values
#Override
protected void onCreate(Bundle savedInstanceState) {
//...
final Spinner spinner = (Spinner) findViewById(R.id.spinner1);
final List<VnosiDB> spinerItems = datasource.getAllNiz();
final ArrayAdapter<VnosiDB> spinnerAdapter = new ArrayAdapter<VnosiDB>(
this, android.R.layout.simple_spinner_item, spinerItems);
spinnerAdapter
.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(spinnerAdapter);
String nizIzSpinerja = spinner.getItemAtPosition(
spinner.getSelectedItemPosition()).toString();
nizDB = nizIzSpinerja;
// nov niz
novNiz = (TextView) findViewById(R.id.dodaj);
novNiz.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
final Dialog dialog = new Dialog(Vnos.this,
android.R.style.Theme_Holo_Dialog);
dialog.setContentView(R.layout.nov_niz);
TextView okNov = (TextView) dialog.findViewById(R.id.okNovNiz);
okNov.setOnClickListener(new android.view.View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
EditText inputNiz = (EditText) dialog
.findViewById(R.id.niz);
dialog.dismiss();
nizDB = inputNiz.getText().toString();
spinnerAdapter.notifyDataSetChanged();
}
});
dialog.show();
}
});
// ...some other code...
//...
//.. then, here I commit everything to database...
shrani = (TextView) findViewById(R.id.shrani);
shrani.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
vnosDB = (int) System.currentTimeMillis();
datasource.createVnos(zacetekDB, razlikaDB, nizDB, deloDB,
postavkaDB, dodatekDB, opisDB, vnosDB);
datasource.close();
Toast test = Toast.makeText(Vnos.this, "Vnos " + deloDB
+ " uspešen!", Toast.LENGTH_LONG);
test.show();
startActivity(new Intent("com.sandpit.jazstudent.URE"));
finish();
}
});
}
}
you are using ArrayAdapter, which is loaded by List<VnosiDB>. I assume that VnosiDB represents a record from the database. Why don't you just put a temporary record in this list when you need it?
List<VnosiDB> spinerItems = new ArrayList<VnosiDB>();
VnosiDB tempRec = new VnosiDB();
//set some values to the properties if you need to
spinnerItems.add(tempRec);
//populate the spinner with the temp record
I am trying to pass information form one Activity to the other and while doing that I would like to have a progress dialog show. Mainly when the second activity is processing the information. I have been reading up and the proper way of doing it seems to be asynctask. Or is there another way of doing it?
Here is my code: Activity one
public class SearchActivity extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.search);
final EditText edittext = (EditText) findViewById(R.id.edittext);
edittext.setOnKeyListener(new OnKeyListener() {
public boolean onKey(View v, int keyCode, KeyEvent event) {
// If the event is a key-down event on the "enter" button
if ((event.getAction() == KeyEvent.ACTION_DOWN)
&& (keyCode == KeyEvent.KEYCODE_ENTER)) {
// Perform action on key press
String query = edittext.getText().toString();
// gets the text and makes sure its a string
Intent intent = new Intent(SearchActivity.this,
DissertationActivity.class);
intent.putExtra("query1", query);
startActivity(intent);
return true;
}
return false;
}
});
final Button button = (Button) findViewById(R.id.searchButton);
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
String query = edittext.getText().toString();
// gets the text and makes sure its a string
Intent intent = new Intent(SearchActivity.this,
DissertationActivity.class);
intent.putExtra("query1", query);
startActivity(intent);
}
});
}
}
This is the Second activity:
public class DissertationActivity extends ListActivity {
/** Called when the activity is first created. */
public ArrayList<String> book_Array = new ArrayList<String>();
ArrayAdapter<String> adapter;
String href = "";
String href1 = "";
String search_Word = "";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle extras = getIntent().getExtras();
search_Word = extras.getString("query1");
adapter = new ArrayAdapter<String>(this, R.layout.list_item_1,
book_Array);
setListAdapter(adapter);
ListView lv = getListView();
lv.setTextFilterEnabled(true);
try {
Document doc = null;
Document guestLink = null;
guestLink = Jsoup.connect("https://aulib.abdn.ac.uk:443/F").get();
Element link = guestLink.select("p > a").first();
href1 = link.attr("href");
href = href1.substring(0, href1.length() - 2); // removes -0 from
// the
// href_Array.add(href); //adds href to the array because string
// wont add to the public var.
doc = Jsoup.connect(
href + "&request=" + search_Word
+ "&find_code=WRD&adjacent=N&x=0&y=0").get();
// System.out.println(doc);
Elements headings = doc.select("td:eq(3)");
// System.out.println(headings);
for (Element heading : headings) {
// System.out.println(heading.text());
String j = heading.text();
book_Array.add(j);
}
} catch (IOException e) {
e.printStackTrace();
}
book_Array.remove(0);
adapter.notifyDataSetChanged();
book_Array.remove(1);
adapter.notifyDataSetChanged();
book_Array.remove(2);
adapter.notifyDataSetChanged();
book_Array.remove("Search");
adapter.notifyDataSetChanged();
book_Array.remove(" | ");
adapter.notifyDataSetChanged();
book_Array.remove(0);
adapter.notifyDataSetChanged();
lv.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> a, View v, int position,
long id) {
// Context context = getApplicationContext();
int query = position;
// String text = book_Array.get(position);
// int duration = Toast.LENGTH_SHORT;
// Toast toast = Toast.makeText(context,
// String.valueOf(position), //shows the postion in the array
// list
// duration);
// toast.show();
Intent intent = new Intent(DissertationActivity.this,
FullDetailsActivity.class);
intent.putExtra("href", href);
intent.putExtra("query1", (int) query);
intent.putExtra("search_Word", search_Word);
startActivity(intent);
}
});
}
}
I tried using:
this.pd = ProgressDialog.show(this, "Working..", "Downloading Data...",
true, false);
But that didn't work.
How would I go about, so that it displays a progress dialog in between the activities?
Thanks for your help!
Calling ProgressDialog.show will block the UI thread. So the progress dialog/bar will not show up until the method has returned. So we can create a thread for our method to run within it. This will avoid blocking the main UI Thread.
Sample code -
ProgressDialog spinnerDialog = ProgressDialog.show(
Placeholder.this, "","Your text ", true);
new Thread(new Runnable() {
public void run() {
//your method code
return;
}
}).start();
Here is my code,
public class SecondScreenActivity extends Activity {
ListView foodJntListView;
ArrayList<Restaurent> restaurentData;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.second_screen);
restaurentData = getFoodJnt();
foodJntListView=(ListView)findViewById(R.id.listView_foodjnt);
foodJntListView.bringToFront();
// setting the adapter to the list
foodJntListView.setAdapter(new RestaurantBaseAdapter(this,restaurentData));
//setting the onclick listener,activity on clicking on an item of the
foodJntListView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
// TODO Auto-generated method stub
String hotelname=restaurentData.get(position).toString();
//things to write
}
});
}
// get all the list of foodjoints
private ArrayList<Restaurent> getFoodJnt() {
// TODO Auto-generated method stub
ArrayList<Restaurent> results=new ArrayList<Restaurent>();
Restaurent restrnt=new Restaurent();
restrnt.setFoodJointname("Ashila");
restrnt.setCuisine("Biriyani,Moughlai");
restrnt.setAddress("Kolkata,E M Bypass");
restrnt.setOpenhours("10:00am-10:00pm");
results.add(restrnt);
restrnt=new Restaurent();
restrnt.setFoodJointname("Bhajohori Manna");
restrnt.setCuisine("Bengali,Chinese");
restrnt.setAddress("Kolkata,Esplanede");
restrnt.setOpenhours("10:00am-10:00pm");
results.add(restrnt);
restrnt=new Restaurent();
restrnt.setFoodJointname("Bar B Q");
restrnt.setCuisine("Bengali,Chinese,Thai");
restrnt.setAddress("Kolkata,Park Street");
restrnt.setOpenhours("10:00am-10:00pm");
results.add(restrnt);
return results;
}
public void makeAToast(String str) {
//yet to implement
Toast toast = Toast.makeText(this, str, Toast.LENGTH_SHORT);
toast.setGravity(Gravity.CENTER, 0, 0);
toast.show();
}
I can able to show a customized listview with a bunch of textview on it as it's item but,I want to get the Name of the restauirants setOnItemClick on the List view.
e.g whenever I click Click on "Bar B Q","calcutta Food Court",it'll show me only "Bar B Q","calcutta Food Court" not other informations.
thnx in advance.Feel free to if u need anything.
"my application screen shot"
assume you've got method like getFoodJointname() in your Restaurent class, you can write the below in your onItemClick():
String hotelname = restaurentData.get(position).getFoodJointname();
makeAToast(hotelname);
this will work hopefully.
Restaurent rest= (Restaurent) foodJntListView.getSelectedItem();
I have a layout like this
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffffff">
<com.ftni.core.ui.ActionBar
android:id="#+id/actionbar"
style="#style/ActionBar"/>
<TextView android:id="#+id/list_title"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Title"
android:textStyle="bold"
android:textColor="#000000"
android:textSize="18sp"
android:padding="3px"/>
<ListView android:id="#id/android:list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:drawSelectorOnTop="false"/>
</LinearLayout>
and in my listview (code that was working before I changed the layout)
private void buildListView()
{
ListView lv = getListView();
registerForContextMenu(lv);
lv.setTextFilterEnabled(true);
lv.clearChoices();
setListAdapter(new UserListAdapter(SuspendedUsersActivity.this, R.layout.useritem, users));
lv.setOnItemClickListener(clickListener);
}
I tried moving the call to setListAdapter first, but I still get the NullPointerException. Here's the logcat
FATAL EXCEPTION: main
java.lang.NullPointerException
at android.app.ListActivity.setListAdapter(ListActivity.java:267)
at com.myapp.backoffice.users.SuspendedUsersActivity.buildListView(SuspendedUsersActivity.java:140)
at com.myapp.backoffice.users.SuspendedUsersActivity.access$0(SuspendedUsersActivity.java:138)
at com.myapp.backoffice.users.SuspendedUsersActivity$2.handleMessage(SuspendedUsersActivity.java:194)
at android.os.Handler.dispatchMessage(Handler.java:99)
I have a feeling that what is happening is that the default ID I was told is correct (#id/android:list) is not correct for the default list view.
EDIT:
Here are more details about how I have this set up.
First, I have an inherited activity to ensure the user is authenticated. When I inherit directly from this class, all works fine.
public class ProtectedListActivity extends ListActivityBase {
boolean isAuthenticated = false;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Thread validationThread = new Thread()
{
#Override
public void run()
{
try
{
isAuthenticated = UserService.ValidateToken();
}
catch (FTNIServiceException e)
{
//eat it
}
finally
{
if (!isAuthenticated)
{
startActivity(new Intent(ProtectedListActivity.this, SignInActivity.class));
finish();
}
}
}
};
validationThread.start();
}
}
Then, I extend that one step further to wrap my default action bar setup into a base class.
public class ListWithActionBarActivity extends ProtectedListActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public void onContentChanged()
{
ActionBar actionBar = (ActionBar)findViewById(R.id.actionbar);
if (actionBar != null)
{
actionBar.setOnTitleClickListener(new OnClickListener() {
public void onClick(View v) {
startActivity(new Intent(ListWithActionBarActivity.this, SelectSiteActivity.class));
finish();
}
});
SiteModel site = PreferencesHelper.getSite();
actionBar.setTitle(site.Name + " (" + site.Abbreviation + ")");
actionBar.addAction(new IntentAction(ListWithActionBarActivity.this,
new Intent(ListWithActionBarActivity.this, MainMenuActivity.class),
R.drawable.ic_title_home_default));
}
}
public static Intent createIntent(Context context) {
Intent i = new Intent(context, MainMenuActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
return i;
}
protected Intent createShareIntent() {
final Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("text/plain");
intent.putExtra(Intent.EXTRA_TEXT, "Shared from the ActionBar widget.");
return Intent.createChooser(intent, "Share");
}
}
Then, because I have 2 lists of users separated by status (suspended or active) I was attempting to wrap an addition to the action bar in a base class.
public class UserBase extends ListWithActionBarActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
//setContentView(R.layout.queue);
super.onCreate(savedInstanceState);
ActionBar actionBar = (ActionBar)findViewById(R.id.actionbar);
actionBar.addAction(new UserStatusSelectorAction(UserBase.this));
}
}
and finally, we have my activity. I've omitted a little code, but I left most of it so you could see how the data is retrieved through another thread while a loading screen is shown, and then the listview is built.
public class SuspendedUsersActivity extends ListWithActionBarActivity implements Runnable{
ProgressDialog progress;
ArrayList<UserModel> users;
int position;
#Override
public void onCreate(Bundle savedInstanceState) {
setContentView(R.layout.queue);
super.onCreate(savedInstanceState);
TextView title = (TextView)findViewById(R.id.list_title);
title.setText("Suspended Users");
progress = ProgressDialog.show(SuspendedUsersActivity.this, "", "Loading...", true);
Thread thread = new Thread(SuspendedUsersActivity.this);
thread.start();
}
private void buildListView()
{
ListView lv = getListView();
//registerForContextMenu(lv);
lv.setTextFilterEnabled(true);
lv.clearChoices();
setListAdapter(new UserListAdapter(SuspendedUsersActivity.this, R.layout.useritem, users));
lv.setOnItemClickListener(clickListener);
}
private OnItemClickListener clickListener = new OnItemClickListener()
{
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
UserModel user = users.get(position);
SuspendedUserAction action = new SuspendedUserAction(SuspendedUsersActivity.this, user.UserId);
action.performAction(view);
}
};
#Override
public void run() {
// TODO Auto-generated method stub
SiteModel site = PreferencesHelper.getSite();
try
{
users = UserService.GetSuspendedUsers(site.SiteId);
}
catch (FTNIServiceException e)
{
// TODO Auto-generated catch block
Message message = new Message();
message.what = ActivityBase.RESULT_ERROR;
message.obj = e.getMessage();
handler.sendMessage(message);
return;
}
handler.sendEmptyMessage(ActivityBase.RESULT_DONE);
}
private Handler handler = new Handler() {
#Override
public void handleMessage(Message msg) {
switch(msg.what)
{
case ActivityBase.RESULT_SUCCESS:
progress.dismiss();
startActivity(new Intent(SuspendedUsersActivity.this, SelectSiteActivity.class));
finish();
break;
case ActivityBase.RESULT_DONE:
buildListView();
ApplicationController app = (ApplicationController)getApplication();
app.setSuspendedUsersChanged(false);
progress.dismiss();
break;
case ActivityBase.RESULT_ERROR:
progress.dismiss();
new AlertDialog.Builder(SuspendedUsersActivity.this)
.setMessage(msg.obj.toString())
.setNeutralButton("Ok", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface arg0, int arg1) {
//do nothing
arg0.dismiss();
}
})
.show();
break;
}
}
};
}
It works with ProtectedListActivity when I do not set a content view, but everything else it fails on, whether or not I set the content view and comment out the actionbar stuff.
Probably you are not setting the value to the ListView global variable.
Post getListView() code to more help.
The NPE is thrown on
setListAdapter(new UserListAdapter(SuspendedUsersActivity.this, R.layout.useritem,
users));
so the users variable is most likely null.
Set a breakpoint right after the line ListView lv = getListView();
Chances are this is giving you a null value.
Honestly I would try to go with a regular activity and just configure the ListView manually. It isn't hard and it seems like a better way to support having two lists in one Activity.
I changed the listview to explicitly give it an id like this
<ListView android:id="#+id/list_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:drawSelectorOnTop="false"/>
And then I changed my code to this
private void buildListView()
{
ListView lv = (ListView)findViewById(R.id.list_view);
lv.setTextFilterEnabled(true);
lv.clearChoices();
lv.setAdapter(new UserListAdapter(SuspendedUsersActivity.this, R.layout.useritem, users));
lv.setOnItemClickListener(clickListener);
}
And now it works. For some reason that default ID for the listview doesn't work.
your must extends MainActivity to ListActivity.
public class MainActivity extends ListActivity {
}