I have a SherlockFragmentActivity class that collects values from a server and loads it in to my database. This SherlockFragmentActivity as 3 Fragment called the Book, Video and Audios. Each of them are meant to show values that were downloaded into the db. By challenge now is when I open my UI i dont get to see the values on the fragments not until I start clicking each fragment before the values get populated into the list in the fragment. And I even notice a continuous addition of this values. My fragment class is pasted below.
public class BooksFragment extends SherlockListFragment{
TextView textview = null;
String CategoryID = null;
ArrayList<HashMap<String,String>> listBooks = null;
IDatabaseHelper databaseHelper = null;
Activity activity = null;
Context context = null;
ListAdapter adapter = null;
public BooksFragment(){
super();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.books, container, false);
// do your view initialization heres
textview = (TextView)view.findViewById(R.id.textView1);
return view;
}
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
listBooks = new ArrayList<HashMap<String,String>>();
}
#Override
public void onStart() {
super.onStart();
Bundle bundle =this.getArguments();
if(bundle != null){
CategoryID = bundle.getString("CategoryID");
}
this.initializeComponents();
this.populateListView();
}
#Override
public void onActivityCreated(Bundle savedInstanceState){
super.onActivityCreated(savedInstanceState);
activity = getActivity();
context = activity.getBaseContext();
databaseHelper= new DatabaseHelper(context);
}
//Now we are going to initialize components of the fragment
private void initializeComponents(){
ListView listview = getListView();
listview.setOnItemClickListener(listener);
}
//list item click listener
private OnItemClickListener listener = new OnItemClickListener(){
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
// TODO Auto-generated method stub
}
};
//This method would be used to collect content from the database and populate the listview item
private void populateListView(){
MedicalBookModel[] booksmodel = this.databaseHelper.ReturnBooks(CategoryID);
if(booksmodel != null){
for(MedicalBookModel book : booksmodel){
HashMap<String,String> bookMap = new HashMap<String,String>();
bookMap.put(MedicalBookModel.MedicalBookModel_ID, book.getID());
bookMap.put(MedicalBookModel.MedicalBookModel_Name,book.getName());
Log.i("values",book.getName());
listBooks.add(bookMap);
}
}
adapter = new SimpleAdapter(context, listBooks,R.layout.list_book,new String[]{ "ID","Name"}, new int[]{ R.id.bookId, R.id.bookName});
setListAdapter(adapter);
}
}
For that you have several solutions :
1- Using the Application instance singleton which is global
2- Creating your own global class to manage your data
3- Use a service bound to the activity (or not) and call backs (maybe intent and broadcast receivers)
4- Pass your object as parceable in argument when adding the fragment
Note that sometimes you will need to invalidate views to force datas to refresh
EXEMPLE OF PARCEABLE OBJECT
public class ImageObject implements Parcelable {
/**
* ATTRIBUTES
*/
protected String _idPicture;
protected String _idAlbum;
protected String _name;
protected String _fileName;
protected String _imageUrl;
protected String _hierarchy;
public ImageObject(String _idPicture, String _idAlbum, String _name, String _fileName, String _imageUrl, String _hierarchy) {
super();
this._idPicture = _idPicture;
this._idAlbum = _idAlbum;
this._name = _name;
this._fileName = _fileName;
this._imageUrl = _imageUrl;
this._hierarchy = _hierarchy;
}
public ImageObject(Parcel in) {
String[] data = new String[6];
in.readStringArray(data);
this._idPicture = data[0];
this._idAlbum = data[1];
this._name = data[2];
this._fileName = data[3];
this._imageUrl = data[4];
this._hierarchy = data[5];
}
public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
public ImageObject createFromParcel(Parcel in) {
return new ImageObject(in);
}
public ImageObject[] newArray(int size) {
return new ImageObject[size];
}
};
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeStringArray(new String[] { this._idPicture, this._idAlbum, this._name, this._fileName, this._imageUrl, this._hierarchy });
}
}
Related
I have this ListView adapter:
public class UpicksAdapter extends BaseAdapter
{
Context context;
List<Upick> upick_list;
public UpicksAdapter(List<Upick> listValue, Context context)
{
this.context = context;
this.upick_list = listValue;
}
#Override
public int getCount()
{
return this.upick_list.size();
}
#Override
public Object getItem(int position)
{
return this.upick_list.get(position);
}
#Override
public long getItemId(int position)
{
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent)
{
ViewItem viewItem = null;
if(convertView == null)
{
viewItem = new ViewItem();
LayoutInflater layoutInfiater = (LayoutInflater)this.context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
convertView = layoutInfiater.inflate(R.layout.listview_items, null);
viewItem.SubNameTextView = (TextView)convertView.findViewById(R.id.SubjectNameTextView);
viewItem.SubFullFormTextView = (TextView)convertView.findViewById(R.id.SubjectFullFormTextView);
convertView.setTag(viewItem);
}
else
{
viewItem = (ViewItem) convertView.getTag();
}
viewItem.SubNameTextView.setText(upick_list.get(position).Subject_Name);
viewItem.SubFullFormTextView.setText(upick_list.get(position).Subject_Full_Form);
return convertView;
}
}
class ViewItem
{
TextView SubNameTextView;
TextView SubFullFormTextView;
}
The ListView is in a fragment.
I need to get data from the listview selected item. I have this listener:
UpicksListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
String item = UpicksListView.getItemAtPosition(position).toString();
Log.d("VALOR","VALOR "+item);
}
});
How can I get the values of the selected item?
EDIT:
Complete Fragment code:
public class MisUpicksFragment extends Fragment {
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
private SessionManager session;
private ProgressDialog loading;
private EditText txtbusqueda;
private Button botonbuscar,botonrefrescar;
//movies
private static final String TAG = MainActivity.class.getSimpleName();
public List<Upick> upicks;
private RecyclerView recyclerView;
private GridLayoutManager gridLayout;
private UpicksAdapter adapter;
// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;
private String user_id;
private Button btnNew;
ListView UpicksListView;
ProgressBar progressBar;
String HttpURL = "http://***/upicks_todos.php";
private OnFragmentInteractionListener mListener;
public MisUpicksFragment() {
// Required empty public constructor
}
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* #param param1 Parameter 1.
* #param param2 Parameter 2.
* #return A new instance of fragment MensajesFragment.
*/
// TODO: Rename and change types and number of parameters
public static MisUpicksFragment newInstance(String param1, String param2) {
MisUpicksFragment fragment = new MisUpicksFragment();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_misupicks, container, false);
UpicksListView = (ListView) view.findViewById(R.id.UpicksListView);
progressBar = (ProgressBar) view.findViewById(R.id.ProgressBar1);
new ParseJSonDataClass(getActivity()).execute();
UpicksListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
String item = UpicksListView.getItemAtPosition(position).toString();
Log.d("VALOR","VALOR "+item);
}
});
return view;
}
private class ParseJSonDataClass extends AsyncTask<Void, Void, Void> {
public Context context;
String FinalJSonResult;
List<Upick> upickFullFormList;
public ParseJSonDataClass(Context context) {
this.context = context;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected Void doInBackground(Void... arg0) {
HttpServiceClass httpServiceClass = new HttpServiceClass(HttpURL);
try {
httpServiceClass.ExecutePostRequest();
if (httpServiceClass.getResponseCode() == 200) {
FinalJSonResult = httpServiceClass.getResponse();
if (FinalJSonResult != null) {
JSONArray jsonArray = null;
try {
jsonArray = new JSONArray(FinalJSonResult);
JSONObject jsonObject;
Upick upick;
upickFullFormList = new ArrayList<Upick>();
for (int i = 0; i < jsonArray.length(); i++) {
upick = new Upick();
jsonObject = jsonArray.getJSONObject(i);
upick.Subject_Name = jsonObject.getString("id_servicio");
upick.Subject_Full_Form = jsonObject.getString("cliente_servicio");
upickFullFormList.add(upick);
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
} else {
Toast.makeText(context, httpServiceClass.getErrorMessage(), Toast.LENGTH_SHORT).show();
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void result)
{
progressBar.setVisibility(View.GONE);
UpicksListView.setVisibility(View.VISIBLE);
if (upickFullFormList != null) {
UpicksAdapter adapter = new UpicksAdapter(upickFullFormList, context);
UpicksListView.setAdapter(adapter);
}
}
}
private void logoutUser() {
session.setLogin(false);
// Launching the login activity
Intent intent = new Intent(getActivity(), LoginActivity.class);
startActivity(intent);
//finish();
}
#Override
public void onDetach() {
super.onDetach();
mListener = null;
}
/**
* This interface must be implemented by activities that contain this
* fragment to allow an interaction in this fragment to be communicated
* to the activity and potentially other fragments contained in that
* activity.
* <p>
* See the Android Training lesson <a href=
* "http://developer.android.com/training/basics/fragments/communicating.html"
* >Communicating with Other Fragments</a> for more information.
*/
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
void onFragmentInteraction(Uri uri);
}
}
Change this code to setters.
upick.Subject_Name = jsonObject.getString("id_servicio");
upick.Subject_Full_Form = jsonObject.getString("cliente_servicio");
eg:
upick.setSubjectname(jsonObject.getString("id_servicio"));
Then inside onclick you can take values using getters
String item = upicks.get(position).getSubjectname();
parent.getItemAtPosition(position) will return an Object (the model used in your adapter).To get some field from your Object don't call Object.toString(); it will return the object reference not the value that you're looking for. Use Object.yourField; instead.
The ArrayList.get() method is used to get the element of a specified
position within the list.
String str_ITEM= upicks.get(position).yourGETMETHOD();
in your callback listener you have adapter object just use that like below.
UpicksListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
String item = parent.getSelectedItem().toString();
Log.d("VALOR","VALOR "+item);
}
});
I am unable to refresh my ListView in ListFragment with new data. Instead the new data is added to the previous.
The time period is from 6AM to 5PM for each entity. Then new data is appended to the list restarting at 6AM for another entity. The data for the first entity should be cleaned before the second is added to the ListView.
Here is the code:
public class FragmentStatePagerSupport extends FragmentActivity {
static final int NUM_ITEMS = 4; //control number of fragments
MyAdapter mAdapter;
ViewPager mPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fragment_main);
mAdapter = new MyAdapter(getSupportFragmentManager());
mPager = (ViewPager)findViewById(R.id.pager);
mPager.setAdapter(null);
mPager.setAdapter(mAdapter);
}
//===============================================================================================
public static class MyAdapter extends FragmentStatePagerAdapter {
public MyAdapter(FragmentManager fm) {
super(fm);
}
#Override
public int getCount() {
return NUM_ITEMS;
}
#Override
public Fragment getItem(int position) {
fragNumber = position;
return ArrayListFragment.newInstance(position);
}
}
//===============================================================================================
public static class ArrayListFragment extends ListFragment {
Integer mNum;
String FORMAT_LINE = "%s%7s%7s%10s%16s";
static ArrayListFragment newInstance(int num) {
ArrayListFragment f = new ArrayListFragment();
Bundle args = new Bundle();
args.putInt("num", num);
f.setArguments(args);
return f;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mNum = getArguments() != null ? getArguments().getInt("num") : 1;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_pager_list, container, false);
View tv = v.findViewById(R.id.text);
View tvd = v.findViewById(R.id.tv_description);
String title = "";
switch (mNum){
case 0:title = MyGlobals.getInstance().getToday();break;
case 1:title = MyGlobals.getInstance().getTomorrow();break;
case 2:title = MyGlobals.getInstance().getDayAfter();break;
case 3:title = MyGlobals.getInstance().getDayDayAfter();break;
}
((TextView) tv).setText(MyGlobals.getInstance().getName() + " on " + title);
((TextView) tvd).setText(String.format(FORMAT_LINE, "time", "temp", "rain", "wind", "weather"));
return v;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
ArrayList<Data> row = Data.getRows(mNum);
ListViewAdapter adapter = new ListViewAdapter(getActivity(), row);
getListView().setAdapter(null);
getListView().setAdapter(adapter);
}
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
v.setBackgroundColor(getResources().getColor(R.color.blue));
}
}
//==============================================================================================
public static class ListViewAdapter extends ArrayAdapter<Data> {
public static class ViewHolder{
TextView time;
TextView temp;
TextView rain;
TextView wind_speed;
TextView weather;
}
public ListViewAdapter(Context context, ArrayList<Data> list) {super(context, R.layout.text_listview, list); }
#Override
public View getView(int position, View convertView, ViewGroup parent) {
Data data = getItem(position);
ViewHolder holder;
if(convertView == null){
holder=new ViewHolder();
LayoutInflater inflater = LayoutInflater.from(getContext());
convertView=inflater.inflate(R.layout.text_listview,parent,false);
holder.time=(TextView) convertView.findViewById(R.id.time);
holder.temp=(TextView) convertView.findViewById(R.id.temp);
holder.rain=(TextView) convertView.findViewById(R.id.rain);
holder.wind_speed=(TextView) convertView.findViewById(R.id.wind);
holder.weather=(TextView) convertView.findViewById(R.id.weather);
convertView.setTag(holder);
}else{
holder=(ViewHolder) convertView.getTag();
}
holder.time.setText(data.time);
holder.temp.setText(data.temp);
holder.rain.setText(data.rain);
holder.wind_speed.setText(data.wind_speed);
holder.weather.setText(data.weather);
return convertView;
}
}
}
This last piece populates the ListView. The calls adapter.clear() and adapter.notifyDataSetChanged() does not resolve the problem.
There is a similar question from 3 years ago How update ListView in ListFragment from FragmentActivity? still without accepted response despite the 6836 views.
Thanks a Lot.
The GetRows(mNum) piece as requested:
public class Data {
public String time;
public String temp;
public String rain;
public String wind_speed;
public String weather;
public Data(String time, String temp, String rain, String wind_speed, String weather) {
this.time = time;
this.temp = temp;
this.rain = rain;
this.wind_speed = wind_speed;
this.weather = weather;
}
public static ArrayList<Data> getRows(int fragNumber) {
int mNum = fragNumber;
int size;
String myList[] = null;
ArrayList<Data> list = new ArrayList<Data>();
switch (mNum) {
case 0://Today
size = MyGlobals.getInstance().getToday("time").size();
myList = new String[size];
for (int i = 0; i < size; i++) {
String time = (String) MyGlobals.getInstance().getToday("time").get(i);
String temp = (String) MyGlobals.getInstance().getToday("temperature").get(i);
String wind_speed = (String) MyGlobals.getInstance().getToday("wind_speed").get(i);
String pop = (String) MyGlobals.getInstance().getToday("pop").get(i);
//String wind_gust = (String) MyGlobals.getInstance().getToday("wind_gust").get(i); //when null breaks code
String weather = (String) MyGlobals.getInstance().getToday("weather").get(i);
if (time.length() == 4) time = "0" + time;
if (wind_speed.length() == 1) wind_speed = "0" + wind_speed;
if (pop.length() == 1) pop = "0" + pop;
list.add(new Data(time,temp,pop,wind_speed,weather));
}
return list;
case 1://Tomorrow
...snip... same as above with pertinent variables,...
case 2://DayAfter
...snip...
case 3://DayDayAfter
...snip....
case 4:// is an error
Log.d("***error***", "list got to case 5");
}
return list;
}
}
Try this;
Before adding new list of Data to the existing list, use list.clear();
Add new Data to the list and you should have only newly added data in the list..
pass the list to your adapter class.
Notify adapter of the new data i.e. adapter.notifyDataSetChanged()
You are returning list twice in your getRows()
remove the "return list" before the case structure
public void onActivityCreated(Bundle savedInstanceState)
{
super.onActivityCreated(savedInstanceState);
// Clear old list here before adding new one.
if (list! = null)
{
list.clear();
}
// Add New list
list = Data.getRows(mNum);
ListViewAdapter adapter = new
ListViewAdapter(getActivity(), list);
getListView().setAdapter(adapter);
adapter.notifyDataSetChange();
}
It's because everytime you set an Adapter, it will really be added., remove all its data first before setting again so it will be like
mPager.setAdapter(null);
before doing
mPager.setAdapter(mAdapter);
Thanks in advance for the help, my code below is taken in a Text File and Displaying it in a ListView, i have Name and youtube in one Line inside the text field.
but what i am looking at trying to do is get the youtube String inside the text file and pass that to my new Activity class as a webview to play the video
just wondering how can this be done, how can i pass this String into my Setters inside my Model class in order to get an Instance of it, do i need to convert String to ArrayListString ?
public class menuFragment extends ListFragment {
ArrayList<model> songList = new ArrayList<model>();
public String[] listSongs = new String[]{};
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.list_fragment, container, false);
loadSongs();
return view;
}
public void loadSongs() {
try {
Resources ResFiles = getResources();
InputStream ReadDbFile = ResFiles.openRawResource(R.raw.songs);
byte[] Bytes = new byte[ReadDbFile.available()];
ReadDbFile.read(Bytes);
String DbLines = new String(Bytes);
listSongs = DbLines.split(",");
ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(),
android.R.layout.simple_list_item_1, listSongs);
setListAdapter(adapter);
} catch (Exception e) {
}
}
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
Intent i = new Intent(getActivity(), playVid.class);
model selectedSong = MainController.getInstance().getSongs().get(position);
i.putExtra("selectedSong", selectedSong);
startActivity(i);
}
public class model implements Serializable {
private String name;
private String url;
public model(String name, String url) {
this.name=name;
this.url = url;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getUrl(){
return url;
}
public void setUrl(String url){
this.url = url;
}
public class MainController
{
private static MainController instance;
private ArrayList<model> songList;
private MainController()
{
this.songList = new ArrayList<model>();
}
public static MainController getInstance()
{
if(instance == null)
{
instance = new MainController();
}
return instance;
}
public void addFlight(String name, String singer, String url)
{
model f = new model(name,singer,url);
this.songList.add(f);
}
public ArrayList<model> getSongs()
{
return this.songList;
}
Suggestion class name should be start with capital - Model.
You have only three variables to pass to another activity, so you can have three putExtra with your intent no need for ArrayList, Sir.
Model selectedSong = MainController.getInstance().getSongs().get(position);
i.putExtra("name", selectedSong.getName());
i.putExtra("singer", selectedSong.getSinger());
i.putExtra("url", selectedSong.getUrl());
startActivity(i);
And inside onCreate of another Activity, we can access these three values like this way,
Intent mIntent = getIntent();
String name = mIntent.getStringExtra("name");
String singer = mIntent.getStringExtra("singer");
String url = mIntent.getStringExtra("url");
First, I'll preface my question with the fact that I'm not using a CursorLoader.
I'm pulling in data from a SQLlite database to populate a listview in a ListFragment. The initial load works well, but once the data is manipulated (i.e. an addition is made to the list), the listview NEVER refreshes to show the new data. I am implementing the Loader callbacks like so:
public class BillListingFragment extends ListFragment implements LoaderManager.LoaderCallbacks<List<Bill>> {
private billListAdapter mAdapter;
private static final int LOADER_ID = 1;
private SQLiteDatabase mDatabase;
private BillsDataSource mDataSource;
private BillsStoreDatabaseHelper mDbHelper;
/**
* The fragment argument representing the fragment type (archive or outstanding)
*/
private static final String ARG_FRAGMENT_TYPE = "fragment_type";
/**
* Returns a new instance of this fragment based on type
*/
public static BillListingFragment newInstance(String type) {
// TODO: Make the fragment type an enum
BillListingFragment fragment = new BillListingFragment();
Bundle args = new Bundle();
args.putString(ARG_FRAGMENT_TYPE, type);
fragment.setArguments(args);
return fragment;
}
public BillListingFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.bill_view_layout, container, false);
return rootView;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mDbHelper = new BillsStoreDatabaseHelper(getActivity());
mDatabase = mDbHelper.getWritableDatabase();
mDataSource = new BillsDataSource(mDatabase);
mAdapter = new billListAdapter(getActivity(), R.layout.bill_row_layout);
setListAdapter(mAdapter);
getLoaderManager().initLoader(LOADER_ID, null, this);
}
#Override
public Loader<List<Bill>> onCreateLoader(int id, Bundle args) {
BillDataLoader loader = new BillDataLoader(getActivity(), mDataSource);
return loader;
}
#Override
public void onLoadFinished(Loader<List<Bill>> loader, List<Bill> data) {
for(Bill bill: data){
mAdapter.add(bill);
}
setListAdapter(mAdapter);
}
#Override
public void onLoaderReset(Loader<List<Bill>> loader) {
mAdapter.clear();
}
#Override
public void onDestroy() {
super.onDestroy();
mDbHelper.close();
mDatabase.close();
mDataSource = null;
mDbHelper = null;
mDatabase = null;
}
public void reload(){
getLoaderManager().restartLoader(LOADER_ID, null, this);
}
private class billListAdapter extends ArrayAdapter<Bill> {
Context context;
public billListAdapter(Context context, int resourceID){
super(context, resourceID);
this.context = context;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = getActivity().getLayoutInflater().inflate(R.layout.bill_row_layout, parent, false);
}
TextView payToField = (TextView) convertView.findViewById(R.id.nameField);
TextView dueDateField = (TextView) convertView.findViewById(R.id.overdueField);
payToField.setText(getItem(position).getPayTo());
// calculate days until due
Bill bill = getItem(position);
// TODO: Add how many days until bill in overdue field + add color
JodaTimeAndroid.init(getActivity());
DateTime dueDateDt = new DateTime(bill.getDateDue());
DateTime currentDt = new DateTime();
int daysDifference = Days.daysBetween(currentDt.toLocalDate(), dueDateDt.toLocalDate()).getDays();
// depending on what that differential looks like set text / color
if (daysDifference > 1) {
dueDateField.setText(Integer.toString(daysDifference) + " Days");
} else {
if (daysDifference == 0) {
dueDateField.setText("DUE TODAY");
} else {
if (daysDifference < 0) {
}
}
}
return convertView;
}
}
}
I have debugged my code so I know that the onLoadFinished callback is being made after the data has been manipulated. I also know that adapter contains the updated data at this point. I have tried resetting the adapter via setListAdapter(mAdatper) and every notifyDataChanged-like method I can find, but to no avail. What is going on here and how can I get the listview to update?
I am developing an android app for students who can take test and exams.Here my question is that I have set of questions say 50 each having 4 answer options in a selectable listview manner.Now,what i want to ask is that i want them to be called in one activity only and not 50 searate activties.
here's the sample code
/***ArrayList goes here*****/
stuff.add("I'm noting.");
stuff.add("I always do nthing.");
stuff.add("All my efforts");
lv = (ListView) findViewById(R.id.list);
ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(
this,
android.R.layout.simple_list_item_1,stuff );
lv.setAdapter(arrayAdapter);
Button sbt=(Button)findViewById(R.id.sbt);
sbt.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent i=new Intent(getApplicationContext(),Screen5cActivity.class);
startActivity(i);
}
});
So,one method for doing this that comes to my mind is that take a static counter and keep on recreating that same activity by inflating data from same arraylist but that method gets a bit obfuscated as for storing result and other.
Any,other solutions withh efficiency and better explaination are welcome.
Okay, well here is how i would do this.
I create a MainActivity as Follows :
public class MainActivity extends FragmentActivity implements QuestionAnswerInterface{
private static final String FRAGMENT_TAG = "QuestionAnswerFragment";
private String [] questionsArray = {"How old was John Wayne when he died ?","Who was the First U.S. President ?", "How many vertices are on a Octagon ?"};
private String [][] answers = {{"43","56","34","none of these"},
{"George Bush","Barrack Obama","George Washington","none of these"},
{"6","4","8","none of these"}
};
private QuestionAnswerFragment fragment = null;
private ArrayList<ArrayList<String>> answersListOfLists = null;
private ArrayList<String> answersList = null;
private ArrayList<String> questionsList = null;
// Ultimate Holder to Link the ArrayLists
private HashMap<ArrayList<String>, ArrayList<ArrayList<String>>> questionAnswerList = null;
#Override protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// -------- Setup the Questions -------
setupQuestions(questionsArray, answers);
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
if(fragment == null)
{
// Create the Fragment
fragment = (QuestionAnswerFragment) QuestionAnswerFragment.newInstance(new Bundle(), "Test Example" , questionAnswerList);
ft.add(R.id.frameLayoutTest, fragment, FRAGMENT_TAG);
ft.commit();
}else{
fragment = (QuestionAnswerFragment) fm.findFragmentByTag(FRAGMENT_TAG);
ft.show(fragment);
}
}
private void setupQuestions(String [] questions, String[][] answers)
{
// The Ultimate Wrapper
questionAnswerList = new HashMap<ArrayList<String>, ArrayList<ArrayList<String>>>();
// ArrayList to hold the List of lists of answers
answersListOfLists = new ArrayList<ArrayList<String>>();
// ArrayList to hold the list of Questions
questionsList = new ArrayList<String>();
// Loop Through the Questions
for(int i = 0; i < questionsArray.length ; i++)
{
// Add them to the List
questionsList.add(questions[i]);
}
//*** Magic Stuff ***
for(int l = 0; l < answers.length ; l++)
{
// Needs to be created each time we add a new set of answers
answersList = new ArrayList<String>();
// Loop through the inner array values
for(int m = 0; m < answers[l].length ; m++)
{
// Add the Answers for index l using values of index m
answersList.add(answers[l][m]);
}
answersListOfLists.add(answersList);
}
questionAnswerList.put(questionsList, answersListOfLists);
}
#Override
public void sendBackAnswer(String answer) {
// TODO Auto-generated method stub
}
}
And then My Fragment Class :
public class QuestionAnswerFragment extends Fragment{
private static HashMap<ArrayList<String>, ArrayList<ArrayList<String>>> m_questionAnswerList;
private static String m_textName = null;
private static final String TAG = "QuestionAnswerFragment";
private QuestionAnswerInterface m_callBack = null;
private AnswerAdapter m_adapter = null;
private ArrayList<ArrayList<String>> m_answers = null;
private ArrayList<String> m_questions = null;
private int m_questionCount = 0;
private String currentQuestion = null;
private Entry<ArrayList<String>, ArrayList<ArrayList<String>>> entry = null;
private Iterator<Entry<ArrayList<String>, ArrayList<ArrayList<String>>>> iterator = null;
// UI Elements
private ListView m_listViewAnswers = null;
private Button m_buttonSubmitAnswer = null;
private TextView m_textViewQuestion = null;
// ----------------------------------------------------------------------------
// Interface
public interface QuestionAnswerInterface
{
// Returns the Right or wrong Answer to be kept for score calculation
public abstract void sendBackAnswer(String answer);
}
// Instance Method, so we can share the relevant information with the fragment
public static QuestionAnswerFragment newInstance(Bundle args, String testName, HashMap<ArrayList<String>, ArrayList<ArrayList<String>>> questionAnswerList)
{
QuestionAnswerFragment fragment = new QuestionAnswerFragment();
m_textName = testName;
m_questionAnswerList = questionAnswerList;
fragment.setArguments(args);
return fragment;
}
// --------------------------------------------------------------------------
// Class Overrides
#Override public void onAttach(Activity activity)
{
// Default Behavior
super.onAttach(activity);
try{
// Attach the Interface to the Parent Activity
m_callBack = (QuestionAnswerInterface) activity;
}catch(ClassCastException ex){
// Log the Error
Log.d(TAG, "Failed to Implement Interface in the Parent Activity " + ex.getMessage());
}
}
#Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
// Inflate the Layout from the XML Resource
return inflater.inflate(R.layout.question_answer_fragment, null);
}
#Override public void onActivityCreated(Bundle savedInstanceState)
{
// TODO Auto-generated method stub
super.onActivityCreated(savedInstanceState);
// Get a Reference to All the Views
m_listViewAnswers = (ListView) getView().findViewById(R.id.listViewAnswerOptions);
m_textViewQuestion = (TextView) getView().findViewById(R.id.textViewQuestion);
m_buttonSubmitAnswer = (Button) getView().findViewById(R.id.buttonDone);
// Add a Listener to the button & ListView
m_buttonSubmitAnswer.setOnClickListener(SubmitListener);
m_listViewAnswers.setOnItemSelectedListener(AnswerListener);
iterator = m_questionAnswerList.entrySet().iterator();
// Start the test from the Beginning using the String [0] as the first question
entry = iterator.next();
m_questions = entry.getKey();
m_answers = entry.getValue();
Log.d("ArraySize Questions", "Size of the Questions Array is "+ m_questions.size());
Log.d("ArraySize Answers", "Size of the Answers Array is "+ m_answers.size());
// Start the Test
updateTest();
}
public void updateTest()
{
m_textViewQuestion.setText(m_questions.get(m_questionCount));
updateAdapter(m_answers.get(m_questionCount));
m_questionCount += 1;
}
private void updateAdapter(ArrayList<String> arrayList)
{
m_adapter = new AnswerAdapter(getActivity(), arrayList);
m_listViewAnswers.setAdapter(m_adapter);
}
private OnItemSelectedListener AnswerListener = new OnItemSelectedListener()
{
#Override public void onItemSelected(AdapterView<?> adapter, View view, int position, long id)
{
// Get the Position of the List Item Selected
// Check if its correct or do what you need to do.
m_callBack.sendBackAnswer(m_listViewAnswers.getSelectedItem().toString());
}
#Override public void onNothingSelected(AdapterView<?> arg0) { }
};
// Submits the Answer to the Parent Activity
private OnClickListener SubmitListener = new OnClickListener()
{
#Override public void onClick(View view)
{
if(m_questionCount != m_questions.size())
{
// Notify the Parent that we want to share the Users choice
updateTest();
}else{
Toast.makeText(getActivity(), "You have reached the End of the Test", Toast.LENGTH_LONG).show();
}
}
};
}
And finally the Adapter Class
public class AnswerAdapter extends BaseAdapter{
//----------------------------------------------------------
// Member Variables
private Context m_classContext = null;
private ArrayList<String> m_answers = null;
private LayoutInflater m_inflater = null;
//----------------------------------------------------------
// Constructor
public AnswerAdapter(Activity activity, ArrayList<String> answers)
{
this.m_classContext = activity;
this.m_answers = answers;
this.m_inflater = LayoutInflater.from(m_classContext);
}
// RowContainer
public class Row
{
TextView m_textAnswer;
CheckBox m_selectedAnswer;
}
// ---------------------------------------------------------
// Class Overrides
#Override public int getCount()
{
int count = 0;
if(m_answers.size() > 0)
{
count = m_answers.size();
}
return count;
}
#Override public Object getItem(int position)
{
// return the Item at the current position
return m_answers.get(position);
}
#Override public long getItemId(int position)
{
// Return the current items position
return position;
}
#Override public View getView(int position, View convertView, ViewGroup parent)
{
Row theRow ;
if(convertView == null){
theRow = new Row();
convertView = m_inflater.inflate(R.layout.answer_row_item, null);
theRow.m_textAnswer = (TextView) convertView.findViewById(R.id.textViewAnswer);
theRow.m_selectedAnswer = (CheckBox) convertView.findViewById(R.id.checkBoxAnswer);
convertView.setTag(theRow);
}else{
theRow = (Row) convertView.getTag();
}
theRow.m_textAnswer.setText(m_answers.get(position).toString());
return convertView;
}
}
So Thats how i would approach this.
Use the Main Activity to Create new Tests, and then use the Interface to Share the results with the parent, so you can calculate totals and scores.
create one Pojo class with variables question.ans1 to ans4
i.e
class Question{
String question;
String ansOne;
String ansTwo;
String ansThree;
String ansFour;
String correctAns;
String selectedAnswer;
}
Now generate an arraylist with 50 questions;
ArrayList list=new ArrayList();
now generate list view with one text view for question and four check boxes for 4 answers.