I've been stuck with this for a long while and it's really frustrating. Basically the app starts off with a ListView containing Movie Titles, their Gross, and Year.
The user then can add a new movie, gross, and year using a different activity from the menu. The values are then returned back to the first activity and is placed at the bottom of the list.
This is where my problem begins. The first problem I had is that the app Force Closes when it's about to display the new item. Now, it doesn't want to display at all. Here's the Code:
public class Lab7_084106 extends ListActivity {
private SampleCustomAdapter adapter;
private ArrayList<MyMovies> movieList;
public static boolean Flag = false;
#SuppressWarnings("null")
#Override
public void onCreate(Bundle savedInstanceState) {
//create stuff
super.onCreate(savedInstanceState);
movieList = new ArrayList<MyMovies>();
Intent data = getIntent();
//Flag = data.getStringExtra("Flag");
String[] oldMovieList = getResources().getStringArray(R.array.movieArray);
String[] oldGrossList = getResources().getStringArray(R.array.worldwideGross);
String[] oldYearList = getResources().getStringArray(R.array.yearArray);
//if there's no new movie to display
if(!Flag){
for (int i = 0; i < oldMovieList.length; i++) {
MyMovies newMovie = new MyMovies();
newMovie.setMovie(oldMovieList[i] + "NEW");
newMovie.setGross(oldGrossList[i]);
newMovie.setYear(oldYearList[i]);
movieList.add(newMovie);
}
//adapter = new SampleCustomAdapter(movieList);
//setContentView(R.layout.row);
//setListAdapter(adapter);
}
else{
Toast.makeText(getApplicationContext(), "Else Entered", Toast.LENGTH_SHORT).show();
int newLength = 50; //oldMovieList.length + 1;
//create new array to store the new value
String[] newMovieArray = new String[newLength];
String[] newGrossArray = new String[newLength];
String[] newYearArray = new String[newLength];
//populate the new list with the old one plus the new one
for (int i = 0; i < newLength; i++) {
if( i != newLength - 1){
newMovieArray[i] = oldMovieList[i];
newGrossArray[i] = oldGrossList[i];
newYearArray[i] = oldYearList[i];
}
else{
newMovieArray[i] = data.getStringExtra("Title");
newGrossArray[i] = data.getStringExtra("Gross");
newYearArray[i] = data.getStringExtra("Year");
}
}
//populate the old one using the new list
for (int i = 0; i < newLength; i++) {
oldMovieList[i] = newMovieArray[i];
oldGrossList[i] = newGrossArray[i];
oldYearList[i] = newYearArray[i];
}
//display stuff
for (int i = 0; i < newLength; i++) {
MyMovies newMovie = new MyMovies();
newMovie.setMovie(oldMovieList[i]);
newMovie.setGross(oldGrossList[i]);
newMovie.setYear(oldYearList[i]);
movieList.add(newMovie);
}
//adapter = new SampleCustomAdapter(movieList);
//setListAdapter(adapter);
}
adapter = new SampleCustomAdapter(movieList);
setListAdapter(adapter);
ListView lv = getListView();
lv.setTextFilterEnabled(true);
//set stuff such that Page2 sends back a result to page 1
lv.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
TextView t = (TextView) view.findViewById(R.id.title);
String name = (String) t.getText();
Toast.makeText(getApplicationContext(), name, Toast.LENGTH_SHORT).show();
}
});
}
private class SampleCustomAdapter extends BaseAdapter {
private ArrayList<MyMovies> internalList;
String[] oldMovieList = getResources().getStringArray(R.array.movieArray);
String[] oldGrossList = getResources().getStringArray(R.array.worldwideGross);
String[] oldYearList = getResources().getStringArray(R.array.yearArray);
private ArrayList<MyMovies> GetSearchResults(){
ArrayList<MyMovies> results = new ArrayList<MyMovies>();
// make sure the arrays have the same length
for (int i = 0; i < oldMovieList.length; i++) {
MyMovies sr = new MyMovies();
sr.setMovie(oldMovieList[i]);
sr.setGross(oldGrossList[i]);
sr.setYear(oldYearList[i]);
results.add(sr);
}
return results;
}
public SampleCustomAdapter(ArrayList<MyMovies> contacts){
internalList = contacts;
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return internalList.size();
}
#Override
public Object getItem(int index) {
// TODO Auto-generated method stub
return internalList.get(index);
}
#Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// NOTE: you can only do this if you have access to the Activity object
// which is why this is an inner class
LayoutInflater inflater = getLayoutInflater();
View view;
//System.out.println(parent.getClass().getName());
//System.out.println(position);
if (convertView==null){
view = inflater.inflate(R.layout.row, null);
}
else{
view = convertView;
}
// extract the views to be populated
TextView movie = (TextView) view.findViewById(R.id.title);
TextView gross = (TextView) view.findViewById(R.id.gross);
TextView date = (TextView) view.findViewById(R.id.date);
// extract the object that will fill these
MyMovies movies = GetSearchResults().get(position);
//MyMovies movies = internalList.get(position);
movie.setText(movies.getMovie());
gross.setText(movies.getGross());
date.setText(movies.getYear());
// return the view
return view;
}
}
//menu lawl
#Override
public boolean onCreateOptionsMenu(Menu menu){
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menupage1, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
//Handle item selection using item.getItemId()
switch(item.getItemId()){
case R.id.addMovie:
AddMovie();
break;
}
return true;
}
//end menu stuff lol
public void AddMovie(){
Intent intent2 = new Intent(this, com.Android.Lab7.addMovie.class);
startActivity(intent2);
finish();
}
}
The Flag Boolean variable basically tells if the user added a movie. If the user added a movie, it will enter the else statement and update from there. I'm really confused where to put this if-else statement.
I ran a few experiments with the GetSearchResult function of SampleCustomAdapter and found out that it directly affects the output of the ListView. I tried placing the if-else statement there but I ended up with a LOT of items in the ListView.
Using adapter.notifyDataSetChanged(); gives a NullPointerException error and points to where I placed it. So even if do something like:
MyMovies newMovie = new MyMovies();
newMovie.setMovie(data.getStringExtra("Title"));
newMovie.setGross(data.getStringExtra("Gross"));
newMovie.setYear(data.getStringExtra("Year"));
movieList.add(newMovie);
adapter.notifyDataSetChanged();
As the else block, it does not work. I think it has something to do with the fact that I'm getting my initial values from the string.xml resource folder and not via hardcode or user input.
This problem has been frustrating me ever since 2-3 days ago and help is really appreciated. Thanks.
you just have to notify the data set Changed on your adapter
movieList.add(newMovie);
adapter.notifyDataSetChanged();
the listview will be updated automatically
UPDATE
you can always use the following it'll work but I prefer notifying the adapter.
movieList.add(newMovie);
adapter = new SampleCustomAdapter(movieList);
setListAdapter(adapter);
you should use adapter.notifyDataSetChanged(). CheckThis Link
Related
I know there are several questions around this, but do not quite get how to solve it.
The problem is that I am showing some values from local SQlite database, the different options are shown ok and I can select them and the value displayed is ok. the problem is that when I try to save it, the getSelectedItem, gets the first item on the list. Any help or suggestions on how to solve it would be great.
Product product = new Product();
productsList = product.getProducts();
Spinner spinnerProduct = findViewById(R.id.spinnerProduct);
String[] arrayProduct = new String[productsList.size()];
for(int i = 0; i < productsList.size(); i++) {
arrayProduct[i] = productsList.get(i).nameProduct;
}
ArrayAdapter<String> adapterProduct = new ArrayAdapter<String>(this,
android.R.layout.simple_spinner_item, arrayProduct);
adapterProduct.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinnerProduct.setAdapter(adapterProduct);
spinnerProduct.setOnItemSelectedListener(onItemSelectedListener1);
String productSelected=spinnerProduct.getSelectedItem().toString();
AdapterView.OnItemSelectedListener onItemSelectedListener1 =
new AdapterView.OnItemSelectedListener(){
#Override
public void onItemSelected(AdapterView<?> parent, View view,
int position, long id) {
Product product = new Product();
productsList = product.getProducts();
int[] arrayProduct = new int[productsList.size()];
for(int i = 0; i < productsList.size(); i++) {
arrayProduct[i] = productsList.get(i).stockCurrent;
}
String productStock = String.valueOf(arrayProduct[position]);
product_amount_available.setText(productStock);
}
#Override
public void onNothingSelected(AdapterView<?> parent) {}
};
A spinner uses Event listening so you cannot just do below in a linear fashion:
spinnerProduct.setOnItemSelectedListener(onItemSelectedListener1);
String productSelected=spinnerProduct.getSelectedItem().toString();
Basically what your code is doing is setting the listener, and immediately after, it's getting some arbitrary/default value from your spinnerProduct object. But you haven't even entered any input to the spinner yet. You must process all the UI and business logic in the event listener's onItemSelected() method only.
You need to implement OnItemSelectedListener and override
public void onItemSelected(AdapterView<?> parent, View view,
int pos, long id) {
// An item was selected. You can retrieve the selected item using
// parent.getItemAtPosition(pos)
}
public void onNothingSelected(AdapterView<?> parent) {
// Another interface callback
}
More info can be found here https://developer.android.com/guide/topics/ui/controls/spinner#SelectListener
Thanks for the help. I solved it. I made the global variables.
int idProduct,idStorage;
String productSelected,storageSelected;
first fill the spinners
Product product = new Product();
productsList = product.getProducts();
Storage storage = new Storage();
storageList = storage.getStorage();
Spinner spinnerProduct = findViewById(R.id.spinnerProduct);
spinnerProduct.setOnItemSelectedListener(this);
Spinner spinnerStorage = findViewById(R.id.spinnerStorage);
spinnerStorage.setOnItemSelectedListener(this);
String[] arrayProduct = new String[productsList.size()];
for(int i = 0; i < productsList.size(); i++) {
arrayProduct[i] = productsList.get(i).nameProduct;
}
ArrayAdapter<String> adapterProduct = new ArrayAdapter<String>(this,
android.R.layout.simple_spinner_item, arrayProduct);
adapterProduct.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinnerProduct.setAdapter(adapterProduct);
spinnerProduct.setOnItemSelectedListener(this);
String[] arrayStorage = new String[storageList.size()];
for(int i = 0; i < storageList.size(); i++) {
arrayStorage[i] = storageList.get(i).nameStorage;
}
ArrayAdapter<String> adapterStorage = new ArrayAdapter<String>(this,
android.R.layout.simple_spinner_item, arrayStorage);
adapterStorage.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinnerStorage.setAdapter(adapterStorage);
spinnerProduct.setOnItemSelectedListener(this);
then, as suggested implemented the onclicklisteners
#Override
public void onItemSelected(AdapterView<?> adapterView, View view, int pos, long l) {
if(adapterView.getId() == R.id.spinnerProduct)
{
idProduct=(int) adapterView.getSelectedItemId();
productSelected=adapterView.getSelectedItem().toString();
Product product = new Product();
productsList = product.getProducts();
int[] arrayProduct = new int[productsList.size()];
for(int i = 0; i < productsList.size(); i++) {
arrayProduct[i] = productsList.get(i).stockCurrent;
}
String productStock = String.valueOf(arrayProduct[pos]);
product_amount_available.setText(productStock);
}
else if(adapterView.getId() == R.id.spinnerStorage)
{
storageSelected=adapterView.getSelectedItem().toString();
idStorage=(int) adapterView.getSelectedItemId();
}
}
#Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
and at last I passed the values into the method triggered by a button
btnSaveTransferProduct.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
saveTransferProduct(idProduct,productSelected, idStorage, storageSelected);
}
}
});
I'm Very new to Java and android... I'm Try to create an ListView using BaseAdapter List being created successfully i have a EditText along with button for each list item but the real problem is when i put some data into editText Field and scroll down to change value of last list item then i go back to the top it refreshes the data to default value it doesn't contain the value which was entered by user before scrolling down
My BaseAdaper Code
class CoustomAdptr extends BaseAdapter{
String[] dates;
Integer[] inventory;
Integer totalrooms;
public CoustomAdptr(RoomFragment roomFragment, String[] dates, Integer[] inventory, Integer totalrooms) {
this.dates = dates;
this.inventory = inventory;
this.totalrooms = totalrooms;
}
#Override
public int getCount() {
return dates.length;
}
#Override
public Object getItem(int i) {
return null;
}
#Override
public long getItemId(int i) {
return 0;
}
#Override
public View getView(final int i, View view, ViewGroup viewGroup) {
view = getLayoutInflater().inflate(R.layout.inventory_listview,null);
TextView textView = (TextView) view.findViewById(R.id.roomListViewText);
final EditText editText = (EditText) view.findViewById(R.id.roomListInventory);
final Button updateButton = (Button) view.findViewById(R.id.roomListViewInventoryUpdateButton);
if(inventory[i] == 0){
editText.setBackgroundColor(getResources().getColor(R.color.SoldOut));
editText.setTextColor(getResources().getColor(R.color.SoldOutTextColor));
} else if(inventory[i] < totalrooms){
editText.setBackgroundColor(getResources().getColor(R.color.invetory));
editText.setTextColor(getResources().getColor(R.color.invetoryTextColor));
} else if(inventory[i] == totalrooms){
editText.setBackgroundColor(getResources().getColor(R.color.fullInventory));
editText.setTextColor(getResources().getColor(R.color.fullInventoryTextColor));
}
editText.setText(String.valueOf(inventory[i]));
textView.setText(dates[i]);
updateButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//String name = editText.getText().toString();
//String name1 = dates[i];
//String name2 = getArguments().getString("room_id");
updateButton.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_done_black_24dp,0,0,0);
//updateButton.setBackgroundColor(getResources().getColor(R.color.SoldOut));
updateButton.setText("Updated");
updateButton.setEnabled(false);
Toast.makeText(getContext(), "Update Inventory Button Clicked", Toast.LENGTH_LONG).show();
}
});
return view;
}
}
This is How Im Passing Data to My Adapter
JSONObject jObj = parentObject.getJSONObject("success");
JSONObject jObj2 = jObj.getJSONObject("data");
JSONArray arrajson = jObj2.getJSONArray("inventories");
String arrayCount = Integer.toString(arrajson.length());
String[] dates = new String[arrajson.length()];
Integer[] inventory = new Integer[arrajson.length()];
Integer totalrooms = new Integer(jObj2.getInt("total_room"));
for (int i=0; i<arrajson.length();i++){
JSONObject jsonObject = arrajson.getJSONObject(i);
dates[i] = jsonObject.getString("date");
inventory[i] = jsonObject.getInt("inventory");
}
CoustomAdptr coustomAdptr = new CoustomAdptr(RoomFragment.this,dates,inventory,totalrooms);
listView.setAdapter(coustomAdptr);
Help Needed :- I Want to retain same visible and Value of edittext as users enters on scroll up or down... i hope i was able to explain my problem clearly
After clicking a button, save it's state in a boolean array or somewhere else. And inside getView method, check if this button was previously clicked or not then setup your view accordingly.
It would be better if you create a model class for rows.
i made a custom listView having two textViews..for example student name and roll no...
now i want to implement a selection...for example..i will click on few students in the listview and the object should get saved somewhere ...for example:
ClassList.add(new StudentList(99,"student1","code"));
ClassList.add(new StudentList(70,"student2","code"));
ClassList.add(new StudentList(20,"student3","code"));
ClassList.add(new StudentList(30,"student4","code"));
adapter = new StudentListViewAdapter(this, ClassList,"code");
listView.setAdapter(adapter);
now i should be able to set another method for example:
ClassList2=listView.getSelectedStudents();
this should return the selected students..for example if i select student 1,student 2 it should return Student List Objects for both of them so i can access there roll and Code too
And there is another problem...when i deselect it should remove that object from the list..
It would be really helpfull if someone will write a sample code
This is how i do it..but i don't think it is really a good method
LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
if (ItemView == null) {
ItemView = inflater.inflate(R.layout.customvistview_atd, parent, false);
}
//find the hotels to work with
final studentlist currentList = totalClass_list.get(position);
//fill the view
final TextView textview_studentName = (TextView) ItemView.findViewById(R.id.textview_atd_studentName);
textview_studentName.setText((currentList.getName()));
final TextView textview_studentRollno = (TextView) ItemView.findViewById(R.id.textview_atd_studentRollno);
textview_studentRollno.setText((currentList.getRoll_no() + ""));
final CardView cardView = (CardView) ItemView.findViewById(R.id.card_view_atd);
cardView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
for (i = 0; i < presentStudents.size(); i++) {
if (presentStudents.get(i).getMindex() == position) {
System.out.println("m-index : "+presentStudents.get(i).getMindex());
System.out.println("position : "+position);
isChecked = true;
System.out.println("I am in the loop, I am at position: "+i);
me = i;
break;
}
}
if (isChecked) {
presentStudents.remove(me);
isChecked = false;
ColorDrawable[] color = {new ColorDrawable(Color.parseColor("#198b9f")), new ColorDrawable(Color.WHITE)};
TransitionDrawable trans = new TransitionDrawable(color);
cardView.setBackground(trans);
trans.startTransition(1500);
textview_studentName.setTextColor(Color.GRAY);
textview_studentName.setTextColor(Color.GRAY);
//cardView.setBackgroundColor(Color.WHITE);
System.out.println("I am in isChecked");
} else {
presentStudents.add(new tempclass(currentList.getRoll_no(),atdCode,position));
ColorDrawable[] colorCard = {new ColorDrawable(Color.WHITE), new ColorDrawable(Color.parseColor("#198b9f"))};
TransitionDrawable trans = new TransitionDrawable(colorCard);
cardView.setBackground(trans);
trans.startTransition(1500);
textview_studentName.setTextColor(Color.WHITE);
textview_studentName.setTextColor(Color.WHITE);
// cardView.setBackgroundColor(Color.BLUE);
System.out.println("I am in else, making it blue");
}
}
});
you can use this one
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
StudentLists studentList = listView.getItemAtPosition(i);//selected object
adapter.dismiss(); // If you want to close the adapter
}
});
I have a ListView and a custom adapter. When the user changes the sort type from a spinner, I want to redraw the list with the new items. The problem is that the ListView is re-drawn only after I interact with it on the device (start scrolling for example).
if (update) {
mOfferList = (ArrayList<PositionSearchItem>) psr
.getPositionSearchItem();
mAdapter.clear();
mAdapter.addAll(mOfferList);
mAdapter.notifydataSetChanged()
mList.invalidate();
mList.invalidateViews();
}
I have also tried to fully reset a new instance of my adapter to the list, it is giving the same result except that the list becomes blank at first and appears on user interaction.
I'm using HoloEveryWhere maybe this is an important info.
EDIT : Here is some more code
#EFragment(R.layout.list_fragment_results)
public class ResultsListFragment extends Fragment {
#ViewById(R.id.search_results_list)
ListView mList;
#ViewById(R.id.search_result_list_spinner)
Spinner mSpinner;
MainActivity mActivity;
private String mTypedText;
private List<String> mSortType;
private ResultsListFragment mFrag;
private Bundle mOffersPageBundle;
private SearchResultsListAdapter mAdapter;
private ArrayList<PositionSearchItem> mOfferList;
#AfterViews
public void afterViews() {
mFrag = this;
mActivity = (MainActivity) getActivity();
mSortType = new ArrayList<String>();
mSortType.add(SearchResultSortType.SCORE_DESCENDING);
mOfferList = new ArrayList<PositionSearchItem>();
mOffersPageBundle = getArguments();
PositionSearchResponse psr = mOffersPageBundle.getParcelable("offers");
mTypedText = mOffersPageBundle.getString("typedText");
mOfferList = (ArrayList<PositionSearchItem>) psr.getPositionSearchItem();
mAdapter = new SearchResultsListAdapter(this,
android.R.layout.simple_list_item_1, mOfferList, mTypedText,
mSortType, mActivity.getLat(), mActivity.getLon());
mList.setAdapter(mAdapter);
this.setListeners();
}
private void setListeners() {
mSpinner.setOnItemSelectedListener(new org.holoeverywhere.widget.AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(
org.holoeverywhere.widget.AdapterView<?> parent, View view,
int pos, long id) {
Boolean update = false;
PositionSearchResponse psr = null;
switch (pos) {
case 0:
if (mSortType.get(0) != SearchResultSortType.SCORE_DESCENDING) {
mSortType.clear();
mSortType.add(SearchResultSortType.SCORE_DESCENDING);
psr = processSearch(mTypedText, mSortType, 0, mActivity);
update = true;
}
break;
case 1:
if (mSortType.get(0) != SearchResultSortType.DATE) {
mSortType.clear();
mSortType.add(SearchResultSortType.DATE);
psr = processSearch(mTypedText, mSortType, 0, mActivity);
update = true;
}
break;
default:
break;
}
if (update) {
mOffersPageBundle.putParcelable("offers", psr);
mOfferList = (ArrayList<PositionSearchItem>) psr
.getPositionSearchItem();
mAdapter.mIdMap.clear();
for (int i = 0; i < mOfferList.size(); ++i) {
mAdapter.mIdMap.put(mOfferList.get(i), i);
}
mOfferList = (ArrayList<PositionSearchItem>) psr
.getPositionSearchItem();
mAdapter.clear();
mAdapter.addAll(mOfferList);
mAdapter.notifydataSetChanged()
mList.invalidate();
mList.invalidateViews();
}
}
#Override
public void onNothingSelected(
org.holoeverywhere.widget.AdapterView<?> parent) {
// TODO Auto-generated method stub
}
});
}
}
EDIT : the getView method from custom adapter
#Override
public View getView(int pos, View convertView, ViewGroup parent) {
this.v = convertView;
LayoutInflater vi = (LayoutInflater) getContext().getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
PositionSearchItem psr = getItem(pos);
v = vi.inflate(R.layout.result_list_item, parent, false);
v.setTag(pos);
// Inject text into view
((TextView) v.findViewById(R.id.result_title_textview))
.setText(getItem(pos).getTitle());
// Disable hardware acceleration for the view (it brakes dotted lines on
// some devices)
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB) {
v.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}
// reload list if scrolled to bottom
int page = 0;
if (pos > mLastViewed && pos == getCount() - 1) {
mLastViewed = pos;
ResultsListFragment frag = new ResultsListFragment_();
PositionSearchResponse newSearch = frag.processSearch(mTypedText, mSortType, mPage,
mActivity);
mPage = mPage + 12;
if(newSearch != null && newSearch.getPositionSearchItem() != null && newSearch.getPositionSearchItem().size() > 0){
for (int i = 0; i < newSearch.getPositionSearchItem().size(); ++i) {
mIdMap.put(newSearch.getPositionSearchItem().get(i), i);
}
this.addAll(newSearch.getPositionSearchItem());
}
}
return v;
}
Use
if (update) {
mAdapter.NotifyDataSetChanged();
}
this may solve your problem.
Try to set the adatpter again.Place the below code in all the places you wrote the code to update listview
mAdapter = new YourAdapter();
mList.setAdapet(mAdapter)
I hope you have created custom list view using adapter and model.
Now each time when you need to update your list view dynamically then you need to clear your previously created list view. Then after you need to fetch all new values and then update same over custom list view.
Hope it helps!
I have an adapter that extends simplecursoradapter. The new view is supposed to take a cursor from a database along with an image, populate a list with a couple of checkboxes. For some reason I can't seem to see, my getView is not even being called. I have a breakpoint inside getView and it never gets there and the list just shows up empty.
Can anyone take a look thru and see what I've done wrong
public class TakeStudentAttendance extends ListActivity {
private gradeBookDbAdapter mDbHelper;
private Long mRowId;
private TextView mNameText;
private String classname;
private Boolean new_attendance = false;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Cursor stud;
mDbHelper = new gradeBookDbAdapter(this);
mDbHelper.open();
mRowId = (savedInstanceState == null) ? null
: (Long) savedInstanceState
.getSerializable(gradeBookDbAdapter.KEY_ROWID);
if (mRowId == null) {
Bundle extras = getIntent().getExtras();
mRowId = extras != null ? extras
.getLong(gradeBookDbAdapter.KEY_ROWID) : null;
}
// pull in class data
stud = mDbHelper.fetchClass(mRowId);
startManagingCursor(stud);
classname = stud.getString(
stud.getColumnIndexOrThrow(gradeBookDbAdapter.KEY_CLASSNAME));
String title = "Attendance for " + classname;
setTitle(title);
setContentView(R.layout.attendance_list);
Button doneButton = (Button) findViewById(R.id.Done);
doneButton.setOnClickListener(mAttendanceActivity);
// check previous attendance date
String prevdate = stud.getString(
stud.getColumnIndexOrThrow(gradeBookDbAdapter.KEY_PREVDATE));
stud = mDbHelper.fetchAttendanceByClass(mRowId); // this query yields _id, name,
// attend, late, dtime
if (mDbHelper.getClassDate() == prevdate){
// previous date is the same, so we're doing attendance again: retain values
new_attendance = false;
}
else {
// dates are different, so we're starting from scratch and all students are
// absent until counted present. I just need names and will populate attendance
new_attendance = true;
// upon attendance start-up, NO ONE is present. Set all entries in DB to not present (0)
setNoAttend(stud, mRowId);
// reset cursor position
stud.moveToFirst();
}
// Create an array to specify the fields we want to display in the list
String[] from = new String[]{gradeBookDbAdapter.KEY_NAME,
gradeBookDbAdapter.KEY_ROWID,
gradeBookDbAdapter.KEY_ATTEND,
gradeBookDbAdapter.KEY_LATE,
gradeBookDbAdapter.KEY_DTIME};
// and an array of the fields we want to bind those fields to (in this case just text1)
int[] to = new int[]{R.id.stuname,
R.id.stuIndex,
R.id.attend,
R.id.late,
R.id.stuIndex};
// Now create a simple cursor adapter and set it to display
// mRowId holds the class index.
MyDataAdapter studs =
new MyDataAdapter(this, R.layout.show_attendance, stud, from, to, mRowId, new_attendance);
setListAdapter(studs);
}
Here's my adapter code:
public class MyDataAdapter extends SimpleCursorAdapter {
private Cursor c;
private Context context;
private Long classnum;
private gradeBookDbAdapter mDbHelper;
private Boolean newValues;
private ArrayList<String> list = new ArrayList<String>();
private ArrayList<Boolean> itemCheckedHere = new ArrayList<Boolean>();
private ArrayList<Boolean> itemCheckedLate = new ArrayList<Boolean>();
private ArrayList<Integer> itemCheckedIdx = new ArrayList<Integer>();
int idxCol;
int idx;
// itemChecked will store the position of the checked items.
public MyDataAdapter(Context context, int layout, Cursor c, String[] from,
int[] to, Long mRowId, Boolean new_attendance) {
super(context, layout, c, from, to);
this.c = c;
this.context = context;
mDbHelper = new gradeBookDbAdapter(context);
mDbHelper.open();
classnum = mRowId;
newValues = new_attendance;
c.moveToFirst();
for (int i = 0; i < c.getCount(); i++) {
itemCheckedHere.add(i, false); // initializes all items value with false
itemCheckedLate.add(i, false); // initializes all items value with false
}
}
public View getView(final int pos, View inView, ViewGroup parent) {
File file;
ImageView studentPhoto;
if (inView == null) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inView = inflater.inflate(R.layout.show_attendance, null);
}
// set up name field
final TextView studentName = (TextView) inView.findViewById(R.id.stuname);
final TextView studentIndex = (TextView) inView.findViewById(R.id.stuIndex);
if (studentName != null)
{
c.moveToPosition(pos);
int index = c.getColumnIndex(gradeBookDbAdapter.KEY_NAME);
String name = c.getString(index);
studentName.setText(name);
index = c.getColumnIndex(gradeBookDbAdapter.KEY_STUDENT);
String Index = c.getString(index);
studentIndex.setText(Index);
// set up photo icon
file = new File(Environment.getExternalStorageDirectory () +
"/gradeBook/" + name + ".jpg");
studentPhoto = (ImageView) inView.findViewById(R.id.icon);
if (file.exists()) {
String fileName = file.getAbsolutePath();
BitmapFactory.Options opts = new BitmapFactory.Options();
Bitmap bm;
bm = BitmapFactory.decodeFile(fileName, opts);
studentPhoto.setImageBitmap(bm);
}
else {
// use icon image
studentPhoto.setImageResource(R.drawable.person_icon);
}
}
final CheckBox cBoxH = (CheckBox) inView.findViewById(R.id.attend);
final CheckBox cBoxL = (CheckBox) inView.findViewById(R.id.late);
cBoxH.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
CheckBox cb = (CheckBox) v.findViewById(R.id.attend);
if (cb.isChecked()) {
itemCheckedHere.set(pos, true);
int Index = new Integer(studentIndex.getText().toString());
mDbHelper.insertAttend(Index, classnum, 1 );
} else if (!cb.isChecked()) {
itemCheckedHere.set(pos, false);
int Index = new Integer(studentIndex.getText().toString());
mDbHelper.deleteAttend(Index, classnum );
}
}
});
cBoxL.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
CheckBox cb = (CheckBox) v.findViewById(R.id.late);
if (cb.isChecked()) {
itemCheckedLate.set(pos, true);
// do some operations here
} else if (!cb.isChecked()) {
itemCheckedLate.set(pos, false);
// do some operations here
}
}
});
cBoxH.setChecked(itemCheckedHere.get(pos)); // this will Check or Uncheck the
cBoxL.setChecked(itemCheckedLate.get(pos)); // this will Check or Uncheck the
// CheckBox in ListView
// according to their original
// position and CheckBox never
// loss his State when you
// Scroll the List Items.
return inView;
}
}
This got answered in the comment, but it might as well get a real answer ^^
getCount() is actually returning 0, so the problem is in the query coming back empty, and not in the adapter.
There can be another reason, why getView is never called. In my case I had two elements in LinearLayout - TextView and ListView. The attribute layout_height of TextView was set to fill_parent and ListView element was out of screen bounds because of this. As getView method is called only when ListView item becomes visible to user, so it has never been called. Changing layout_height property to wrap_content solved this problem.
Another thing is to make sure you have called setContentView() with the appropriate argument.