I make Android application with master/detail pattern. So I have
ListActivity class which is FragmentActivity and
ListFragment class which is Fragment
It all works perfect, but when I change screen orientation it calls again AsyncTask and reload all data.
Here is the code for ListActivity class where I handle all logic:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list);
getActionBar().setDisplayHomeAsUpEnabled(true);
getActionBar().setHomeButtonEnabled(true);
getActionBar().setTitle("Dnevni horoskop");
if(findViewById(R.id.details_container) != null){
//Tablet
mTwoPane = true;
//Fragment stuff
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
DetailsFragment df = new DetailsFragment();
ft.add(R.id.details_container, df);
ft.commit();
}
pb = (ProgressBar) findViewById(R.id.pb_list);
tvNoConnection = (TextView) findViewById(R.id.tv_no_internet);
ivNoConnection = (ImageView) findViewById(R.id.iv_no_connection);
list = (GridView) findViewById(R.id.gv_list);
if(mTwoPane == true){
list.setNumColumns(1);
//list.setPadding(16,16,16,16);
}
adapter = new CustomListAdapter();
list.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int position,
long arg3) {
pos = position;
if(mTwoPane == false){
Bundle bundle = new Bundle();
bundle.putSerializable("zodiac", zodiacFeed);
Intent i = new Intent(getApplicationContext(), DetailsActivity.class);
i.putExtra("position", position);
i.putExtras(bundle);
startActivity(i);
overridePendingTransition(R.anim.right_in, R.anim.right_out);
}
else if(mTwoPane == true){
DetailsFragment fragment = (DetailsFragment) getSupportFragmentManager().findFragmentById(R.id.details_container);
fragment.setHoroscopeText(zodiacFeed.getItem(position).getText());
fragment.setLargeImage(zodiacFeed.getItem(position).getLargeImage());
fragment.setSign("Dnevni horoskop - "+zodiacFeed.getItem(position).getName());
fragment.setSignDuration(zodiacFeed.getItem(position).getDuration());
// inflate menu from xml
/*if(menu != null){
MenuItem item = menu.findItem(R.id.share);
Toast.makeText(getApplicationContext(), item.getTitle().toString(), Toast.LENGTH_SHORT).show();
}*/
}
}
});
if(!Utils.isConnected(getApplicationContext())){
pb.setVisibility(View.GONE);
tvNoConnection.setVisibility(View.VISIBLE);
ivNoConnection.setVisibility(View.VISIBLE);
}
//Calling AsyncTask to load data
Log.d("TAG", "loading");
HoroscopeAsyncTask task = new HoroscopeAsyncTask(pb);
task.execute();
}
#Override
public void onConfigurationChanged(Configuration newConfig) {
// TODO Auto-generated method stub
super.onConfigurationChanged(newConfig);
}
class CustomListAdapter extends BaseAdapter {
private LayoutInflater layoutInflater;
public CustomListAdapter() {
layoutInflater = (LayoutInflater) getBaseContext().getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
}
public int getCount() {
// TODO Auto-generated method stub
// Set the total list item count
return names.length;
}
public Object getItem(int arg0) {
// TODO Auto-generated method stub
return null;
}
public long getItemId(int arg0) {
// TODO Auto-generated method stub
return 0;
}
public View getView(int position, View convertView, ViewGroup parent) {
// Inflate the item layout and set the views
View listItem = convertView;
int pos = position;
zodiacItem = zodiacList.get(pos);
if (listItem == null && mTwoPane == false) {
listItem = layoutInflater.inflate(R.layout.list_item, null);
}
else if(mTwoPane == true){
listItem = layoutInflater.inflate(R.layout.tablet_list_item, null);
}
// Initialize the views in the layout
ImageView iv = (ImageView) listItem.findViewById(R.id.iv_horoscope);
iv.setScaleType(ScaleType.CENTER_CROP);
TextView tvName = (TextView) listItem.findViewById(R.id.tv_zodiac_name);
TextView tvDuration = (TextView) listItem.findViewById(R.id.tv_duration);
iv.setImageResource(zodiacItem.getImage());
tvName.setText(zodiacItem.getName());
tvDuration.setText(zodiacItem.getDuration());
Animation animation = AnimationUtils.loadAnimation(getBaseContext(), R.anim.push_up);
listItem.startAnimation(animation);
animation = null;
return listItem;
}
}
private void getHoroscope() {
String urlString = "http://balkanandroid.com/download/horoskop/examples/dnevnihoroskop.php";
try {
HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost(urlString);
HttpResponse response = client.execute(post);
resEntity = response.getEntity();
response_str = EntityUtils.toString(resEntity);
if (resEntity != null) {
Log.i("RESPONSE", response_str);
runOnUiThread(new Runnable() {
public void run() {
try {
Log.d("TAG", "Response from server : n "
+ response_str);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
} catch (Exception ex) {
Log.e("TAG", "error: " + ex.getMessage(), ex);
}
}
private class HoroscopeAsyncTask extends AsyncTask<String, Void, Void> {
public HoroscopeAsyncTask(ProgressBar pb1){
pb = pb1;
}
#Override
protected void onPreExecute() {
pb.setVisibility(View.VISIBLE);
super.onPreExecute();
}
#Override
protected Void doInBackground(String... params) {
getHoroscope();
try {
Log.d("TAG", "test u try");
JSONObject jsonObject = new JSONObject(response_str);
JSONArray jsonArray = jsonObject.getJSONArray("horoscope");
for(int i=0;i<jsonArray.length();i++){
Log.d("TAG", "test u for");
JSONObject horoscopeObj = jsonArray.getJSONObject(i);
String horoscopeSign = horoscopeObj.getString("name_sign");
String horoscopeText = horoscopeObj.getString("txt_hrs");
zodiacItem = new ZodiacItem(horoscopeSign, horoscopeText, duration[i], images[i], largeImages[i]);
zodiacList.add(zodiacItem);
zodiacFeed.addItem(zodiacItem);
//Treba u POJO klasu ubaciti sve.
Log.d("TAG", "ZNAK: "+zodiacItem.getName()+" HOROSKOP: "+zodiacItem.getText());
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Log.e("TAG", "error: " + e.getMessage(), e);
}
return null;
}
#Override
protected void onPostExecute(Void result) {
pb.setVisibility(View.GONE);
list.setAdapter(adapter);
adapter.notifyDataSetChanged();
super.onPostExecute(result);
}
}
Here is the code for ListFragment class:
public class ListFragment extends Fragment {
#Override
public void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
// Retain this fragment across configuration changes.
setRetainInstance(true);
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
View view = inflater.inflate(R.layout.fragment_list, container, false);
return view;
}
}
I believe part of the problem could be that the orientation change calls onCreate again.
See this question, and check the second answer.
Just adding configChanges to android manifest won't solve the problem, but if you override onConfigurationChanged, you could for example, set a SharedPreferences value were you say "AsynTaskStarted=true" or something like that, so when the orientation changes, you can check this flag and either start the AsyncTask if not present, r just skip that if it's already running.
This other question, referenced by the first answer to the first question linked, seems to have more info.
when orientation changes you can use the following to retain the task:
#Override
public HoroscopeAsyncTask onRetainCustomNonConfigurationInstance() {
return task;
}
then in your onCreate() you can do something like this:
task = (HoroscopeAsyncTask)this.getLastCustomNonConfigurationInstance();
if(task != null) {
//pass the new progressbar reference to the asynctask
//implement a method in the asynctask that returns the task result
//e.g. result = task.getResult();
// if the result is not null, it means the task finished its work while orientation
// changed, if the result is null, onPostExecute will take care of that.
//if(result != null) { //set the result in the listview }
} else {
HoroscopeAsyncTask task = new HoroscopeAsyncTask(pb);
task.execute();
}
the code is trying to get the retained taks, if there isn't one (app started) execute a new asynctask, if there is one (orientation change) use the existing running asynctask.
try this code in manifest m8 android:configChanges="orientation|keyboardHidden"
Related
I am developing an app in which my previous colleague used GridView to show data,but i want to use recyclerview with cardadapter, but I am not getting how to do that.
Here is my code for mainActivity:
public class ActivityCategoryList extends Activity {
GridView listCategory;
ProgressBar prgLoading;
TextView txtAlert;
// declare adapter object to create custom category list
AdapterCategoryList cla;
// create arraylist variables to store data from server
static ArrayList<Long> Category_ID = new ArrayList<Long>();
static ArrayList<String> Category_name = new ArrayList<String>();
static ArrayList<String> Category_image = new ArrayList<String>();
String CategoryAPI;
int IOConnect = 0;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.category_list);
ActionBar bar = getActionBar();
bar.setBackgroundDrawable(new ColorDrawable(getResources().getColor(R.color.header)));
bar.setDisplayHomeAsUpEnabled(true);
bar.setHomeButtonEnabled(true);
bar.setTitle("Category");
prgLoading = (ProgressBar) findViewById(R.id.prgLoading);
listCategory = (GridView) findViewById(R.id.listCategory);
txtAlert = (TextView) findViewById(R.id.txtAlert);
cla = new AdapterCategoryList(ActivityCategoryList.this);
// category API url
CategoryAPI = Constant.CategoryAPI+"?accesskey="+Constant.AccessKey;
// call asynctask class to request data from server
new getDataTask().execute();
// event listener to handle list when clicked
listCategory.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> arg0, View arg1, int position,
long arg3) {
// TODO Auto-generated method stub
// go to menu page
Intent iMenuList = new Intent(ActivityCategoryList.this, ActivityMenuList.class);
iMenuList.putExtra("category_id", Category_ID.get(position));
iMenuList.putExtra("category_name", Category_name.get(position));
startActivity(iMenuList);
overridePendingTransition(R.anim.open_next, R.anim.close_next);
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_category, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
switch (item.getItemId()) {
case R.id.cart:
// refresh action
Intent iMyOrder = new Intent(ActivityCategoryList.this, ActivityCart.class);
startActivity(iMyOrder);
overridePendingTransition (R.anim.open_next, R.anim.close_next);
return true;
case R.id.refresh:
IOConnect = 0;
listCategory.invalidateViews();
clearData();
new getDataTask().execute();
return true;
case android.R.id.home:
// app icon in action bar clicked; go home
this.finish();
overridePendingTransition(R.anim.open_main, R.anim.close_next);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
// clear arraylist variables before used
void clearData(){
Category_ID.clear();
Category_name.clear();
Category_image.clear();
}
// asynctask class to handle parsing json in background
public class getDataTask extends AsyncTask<Void, Void, Void>{
// show progressbar first
getDataTask(){
if(!prgLoading.isShown()){
prgLoading.setVisibility(0);
txtAlert.setVisibility(8);
}
}
#Override
protected Void doInBackground(Void... arg0) {
// TODO Auto-generated method stub
// parse json data from server in background
parseJSONData();
return null;
}
#Override
protected void onPostExecute(Void result) {
// TODO Auto-generated method stub
// when finish parsing, hide progressbar
prgLoading.setVisibility(8);
// if internet connection and data available show data on list
// otherwise, show alert text
if((Category_ID.size() > 0) && (IOConnect == 0)){
listCategory.setVisibility(0);
listCategory.setAdapter(cla);
}else{
txtAlert.setVisibility(0);
}
}
}
// method to parse json data from server
public void parseJSONData(){
clearData();
try {
// request data from Category API
HttpClient client = new DefaultHttpClient();
HttpConnectionParams.setConnectionTimeout(client.getParams(), 15000);
HttpConnectionParams.setSoTimeout(client.getParams(), 15000);
HttpUriRequest request = new HttpGet(CategoryAPI);
HttpResponse response = client.execute(request);
InputStream atomInputStream = response.getEntity().getContent();
BufferedReader in = new BufferedReader(new InputStreamReader(atomInputStream));
String line;
String str = "";
while ((line = in.readLine()) != null){
str += line;
}
// parse json data and store into arraylist variables
JSONObject json = new JSONObject(str);
JSONArray data = json.getJSONArray("data");
for (int i = 0; i < data.length(); i++) {
JSONObject object = data.getJSONObject(i);
JSONObject category = object.getJSONObject("Category");
Category_ID.add(Long.parseLong(category.getString("Category_ID")));
Category_name.add(category.getString("Category_name"));
Category_image.add(category.getString("Category_image"));
Log.d("Category name", Category_name.get(i));
}
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
IOConnect = 1;
e.printStackTrace();
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
#Override
protected void onDestroy() {
// TODO Auto-generated method stub
//cla.imageLoader.clearCache();
listCategory.setAdapter(null);
super.onDestroy();
}
#Override
public void onConfigurationChanged(final Configuration newConfig)
{
// Ignore orientation change to keep activity from restarting
super.onConfigurationChanged(newConfig);
}
#Override
public void onBackPressed() {
// TODO Auto-generated method stub
super.onBackPressed();
finish();
overridePendingTransition(R.anim.open_main, R.anim.close_next);
}
}
Here is the Code for Adapter Class:
class AdapterCategoryList extends BaseAdapter {
private Activity activity;
public ImageLoader imageLoader;
public AdapterCategoryList(Activity act) {
this.activity = act;
imageLoader = new ImageLoader(act);
}
public int getCount() {
// TODO Auto-generated method stub
return ActivityCategoryList.Category_ID.size();
}
public Object getItem(int position) {
// TODO Auto-generated method stub
return position;
}
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
ViewHolder holder;
if(convertView == null){
LayoutInflater inflater = (LayoutInflater) activity
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.category_list_item, null);
holder = new ViewHolder();
convertView.setTag(holder);
}else{
holder = (ViewHolder) convertView.getTag();
}
holder.txtText = (TextView) convertView.findViewById(R.id.txtText);
holder.imgThumb = (ImageView) convertView.findViewById(R.id.imgThumb);
holder.txtText.setText(ActivityCategoryList.Category_name.get(position));
imageLoader.DisplayImage(Constant.AdminPageURL+ActivityCategoryList.Category_image.get(position), holder.imgThumb);
return convertView;
}
static class ViewHolder {
TextView txtText;
ImageView imgThumb;
}
}
I am new to this, and I think for recyclerview we need to create a list class also.
If anyone have any idea about this, can you help me?
I didn't check your whole code, but the key steps to archieve this is:
set an adapter
recyclerView.setAdapter(adpter);
and create and set an LayoutManager
int columns=3;
reyclerView.setLayoutManager(new GridLayoutManager(context,columns););
see RecyclerView docs and GridLayoutManager
GridView is different and GridLayoutManager is different.So, first you will have to create a recyclerview with the GridLayoutManager.
Remove GridView from respective xml and use Recyclerview with GridLayoutManager
Create Recycler Adapter using the AdapterCategoryList
I've custom adapter that populates custom listview with data fetched from server. What I want is check if adapter is empty and append data to listview if it is empty else fill the listview with data and notifyDataSetChanged. I'm implementing OnScrollListener to load more data from server. But adapter never is empty and always notifyDataSetChanged is called.
My List Activity
public class ListResultActivity extends Activity implements OnScrollListener{
private ArrayList<BusinessListData> businesses;
private ListView businessList;
private LayoutInflater layoutInflator;
private BusinessListIconTask imgFetcher;
BusinessListDataAdapter adapter;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.businesslist);
this.businessList = (ListView) findViewById(R.id.lvBusinesslist);
this.adapter= new BusinessListDataAdapter(this,
this.imgFetcher, this.layoutInflator, this.businesses);
getData();
businessList.setOnScrollListener(this);
}
#Override
public Object onRetainNonConfigurationInstance() {
Object[] myStuff = new Object[2];
myStuff[0] = this.businesses;
myStuff[1] = this.imgFetcher;
return myStuff;
}
/**
* Bundle to hold refs to row items views.
*
*/
public static class MyViewHolder {
public TextView businessName, businessAddress, phoneNo;
public Button btnProfile;
public ImageView icon;
public BusinessListData business;
}
public void setBusinesses(ArrayList<BusinessListData> businesses) {
this.imgFetcher = new BusinessListIconTask(this);
this.layoutInflator = LayoutInflater.from(this);
this.businesses = businesses;
if(adapter !=null){
this.adapter.notifyDataSetChanged();
}else{
this.adapter= new BusinessListDataAdapter(this,
this.imgFetcher, this.layoutInflator, this.businesses);
businessList.setAdapter(adapter);
}
}
private void getData() {
// TODO Auto-generated method stub
Intent myIntent = getIntent();
// gets the arguments from previously created intent
String metroTxt = myIntent.getStringExtra("key");
String metroLoc = myIntent.getStringExtra("loc");
String metroId = myIntent.getStringExtra("qt");
BusinessListApiTask spTask = new BusinessListApiTask(
ListResultActivity.this);
try {
spTask.execute(metroTxt, metroLoc, metroId);
} catch (Exception e) {
spTask.cancel(true);
}
}
#Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
// TODO Auto-generated method stub
}
#Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
// TODO Auto-generated method stub
if (businessList.getLastVisiblePosition() == totalItemCount - 1) {
getData();
adapter.notifyDataSetChanged();
Log.d("test count", "abc"+totalItemCount);
}
}
}
Class to fetch data from server and set to adapter
public class BusinessListApiTask extends AsyncTask<String, Integer, String> {
private ProgressDialog progDialog;
private Context context;
private ListResultActivity activity;
private static final String debugTag = "sodhpuch";
HashMap<String, String> queryValues;
/**
* Construct a task
*
* #param activity
*/
public BusinessListApiTask(ListResultActivity activity) {
// TODO Auto-generated constructor stub
super();
this.activity = activity;
this.context = this.activity.getApplicationContext();
}
#Override
protected void onPreExecute() {
super.onPreExecute();
progDialog = ProgressDialog.show(this.activity, "Search", this.context
.getResources().getString(R.string.looking_for_business), true,
false);
}
#Override
protected String doInBackground(String... params) {
try {
// Log.d(debugTag, "Background:" +
// Thread.currentThread().getName());
String result = BusinessListHelper.downloadFromServer(params);
// try {
//
// updateSQLite(result);
//
// } catch (Exception e) {
// return result;
// }
Log.d("result", result);
return result;
} catch (Exception e) {
return new String();
}
}
#Override
protected void onPostExecute(String result) {
ArrayList<BusinessListData> businessData = new ArrayList<BusinessListData>();
progDialog.dismiss();
try {
JSONObject respObj = new JSONObject(result);
int success = respObj.getInt("success");
Log.d("Success", "abc"+success);
if (success == 1) {
JSONArray tracks = respObj.getJSONArray("idioms");
for (int i = 0; i < tracks.length(); i++) {
JSONObject track = tracks.getJSONObject(i);
String businessName = track.getString("name");
String businessAddress = track.getString("address");
String phone = track.getString("phone");
String id = track.getString("id");
String deals_in = track.getString("deals_in");
businessData.add(new BusinessListData(businessName,
businessAddress, id, phone, deals_in));
}
} else {
Log.d("Success", "first"+success);
// Log.d(debugTag, "Background:" + result);
// DBController controller = new DBController(context);
// businessData = controller.getBusinessList();
return ;
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// }
this.activity.setBusinesses(businessData);
}
My Adapter
public class BusinessListDataAdapter extends BaseAdapter implements
OnClickListener {
private static final String debugTag = "BusinessListDataAdapter";
private ListResultActivity activity;
private BusinessListIconTask imgFetcher;
private LayoutInflater layoutInflater;
private ArrayList<BusinessListData> businesses;
BusinessListData business;
public BusinessListDataAdapter(ListResultActivity a,
BusinessListIconTask i, LayoutInflater l,
ArrayList<BusinessListData> data) {
this.activity = a;
this.imgFetcher = i;
this.layoutInflater = l;
this.businesses = data;
}
#Override
public int getCount() {
return this.businesses.size();
}
public void clear()
{
businesses.clear();
notifyDataSetChanged();
}
#Override
public boolean areAllItemsEnabled() {
return true;
}
#Override
public Object getItem(int arg0) {
return null;
}
#Override
public long getItemId(int pos) {
return pos;
}
#Override
public View getView(int pos, View convertView, ViewGroup parent) {
MyViewHolder holder;
if (convertView == null) {
convertView = layoutInflater.inflate(R.layout.trackrow, parent,
false);
holder = new MyViewHolder();
holder.businessName = (TextView) convertView
.findViewById(R.id.tvBusinessName);
holder.businessAddress = (TextView) convertView
.findViewById(R.id.tvAddress);
holder.phoneNo = (TextView) convertView.findViewById(R.id.tvPhone);
holder.icon = (ImageView) convertView.findViewById(R.id.album_icon);
holder.btnProfile = (Button) convertView
.findViewById(R.id.btnProfile);
holder.btnProfile.setTag(holder);
convertView.setTag(holder);
} else {
holder = (MyViewHolder) convertView.getTag();
}
convertView.setOnClickListener(this);
business= businesses.get(pos);
holder.business = business;
holder.businessName.setText(business.getName());
holder.businessAddress.setText(business.getAddress());
holder.phoneNo.setText(business.getPhone());
holder.btnProfile.setOnClickListener(this);
// if(track.getImageUrl() != null) {
// holder.icon.setTag(track.getImageUrl());
// Drawable dr = imgFetcher.loadImage(this, holder.icon);
// if(dr != null) {
// holder.icon.setImageDrawable(dr);
// }
// } else {
holder.icon.setImageResource(R.drawable.filler_icon);
// }
return convertView;
}
#Override
public void onClick(View v) {
String deals_in = business.getDeals().toString();
Log.d("name", deals_in);
MyViewHolder holder = (MyViewHolder) v.getTag();
if (v instanceof Button) {
Intent profile = new Intent(activity,
ProfileActivity.class);
profile.putExtra("deals_in", deals_in);
profile.putExtra("phone", holder.business.getPhone());
profile.putExtra("address", holder.business.getAddress());
profile.putExtra("name", holder.business.getName());
this.activity.startActivity(profile);
} else if (v instanceof View) {
Log.d("test","call testing");
Intent intent = new Intent(Intent.ACTION_CALL);
intent.setData(Uri.parse("tel:" +holder.business.getPhone()));
this.activity.startActivity(intent);
}
Log.d(debugTag, "OnClick pressed.");
}
}
Try this way,hope this will help you to solve your problem.
public void setBusinesses(ArrayList<BusinessListData> businesses) {
imgFetcher = new BusinessListIconTask(this);
layoutInflator = LayoutInflater.from(this);
if(this.businesses == null || adapter==null){
this.businesses = new ArrayList<BusinessListData>();
adapter= new BusinessListDataAdapter(this,imgFetcher,layoutInflator,this.businesses);
businessList.setAdapter(adapter);
}
this.businesses.addAll(businesses);
adapter.notifyDataSetChanged();
}
You have the adapter object in your setBusinesses Method. You just need to check the size of the adapter too as follows which is solve your problem.
if(adapter !=null && adapter.getCount()>0)
{
this.adapter.notifyDataSetChanged();
}
else
{
this.adapter= new BusinessListDataAdapter(this,
this.imgFetcher, this.layoutInflator, this.businesses);
businessList.setAdapter(adapter);
}
this will check the size of your BusinessListData object in the adapter and this will not initialize the adapter again and again.
Hope this Solves your problem.
Thank You!
Change use of OnScrollListener. Use Asynctask class and onPreExecute() set adapter as null. Load data in doInBackground() method and call custom adapter in onPostExecute(). I hope it 'll work fine.
My code is reachable but the adapter just doesnt work. The listview doesnt show and the fragment remains empty.
I re-populate my list at OnResume.
my code:
public class mylist extends ListFragment {
public void ToastLoadShout(String msg) {
Toast.makeText(getActivity(), msg.toString(), Toast.LENGTH_LONG).show();
}
private static View View;
HttpClient client;
HttpPost httppost;
HttpGet httpget;
JSONObject json;
List<List<String>> items;
List<item> markers = new ArrayList<item>();
MobileArrayAdapter adapter;
ListView list;
ProgressBar listload;
Button relist;
Preferences pref;
String datadata = "";
String savedlat="0.0";
String savedlon="0.0";
boolean isLoaded=false;
int index;
int top;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.activity_list, container, false);
}
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public void onResume(){
super.onResume();
// Recreate the adapter from the new feed
adapter = new MobileArrayAdapter(getActivity(), markers);
// Set the recreated adapter
list.setAdapter(adapter);
ToastLoadShout("reached here");
if (!(items==null))
ToastLoadShout("there are items");
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
if (!isLoaded){
try {
pref = new Preferences(getActivity());
list = (ListView) getView().findViewById(android.R.id.list);
listload = (ProgressBar) getView().findViewById(R.id.listload);
HashMap<String, String> loc = pref.getData();
ToastLoadShout(loc.get(Preferences.LAT) + ","
+ loc.get(Preferences.LON));
if (loc.get(Preferences.LAT) != null && !loc.get(Preferences.LAT).equals("0.0"))
{
if (loc.get(Preferences.LAT) != savedlat && loc.get(Preferences.LON)!=savedlon){
new Load().execute();
savedlat=loc.get(Preferences.LAT);
savedlon=loc.get(Preferences.LON);
}
}
else
ToastLoadShout("Get Location First.");
relist = (Button) getView().findViewById(R.id.relist);
relist.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
listload.setVisibility(View.INVISIBLE);
HashMap<String, String> loc = pref.getData();
ToastLoadShout(loc.get(Preferences.LAT) + ","
+ loc.get(Preferences.LON));
if (loc.get(Preferences.LAT) != null && !loc.get(Preferences.LAT).equals("0.0")){
adapter.deleteList();
list.destroyDrawingCache();
new Load().execute();}
else
ToastLoadShout("Get Location First.");
}});
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
list.setOnScrollListener(new OnScrollListener() {
#Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
//Check if the last view is visible
index = list.getFirstVisiblePosition();
View v = list.getChildAt(0);
top = (v == null) ? 0 : v.getTop();
}
#Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
// TODO Auto-generated method stub
}
});
}
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
// get selected items
//String selectedValue = (String) getListAdapter().getItem(position);
String selectedValue = markers.get(position).getTitle();
Toast.makeText(getActivity(), selectedValue, Toast.LENGTH_SHORT).show();
}
class Load extends AsyncTask<String, Integer, Boolean> {
#Override
protected void onPreExecute() {
listload.setVisibility(View.VISIBLE);
isLoaded=true;
ToastLoadShout("preExecute");
}
#Override
protected Boolean doInBackground(String... params) {
try {
items = DownloadList();
if (items != null)
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
return false;
}
#Override
protected void onPostExecute(Boolean res) {
// TODO Auto-generated method stub
if (res) {
ArrangePutMarkers();
adapter=new MobileArrayAdapter(getActivity(), markers);
list.setAdapter(adapter);
} else {
ToastLoadShout("Error");
ToastLoadShout(datadata);
}
listload.setVisibility(View.INVISIBLE);
ToastLoadShout("PostExecute");
}
}
public void onBackPressed() {
}
}
Call notifydatasetchanged method of your adapter after you change its contents. Your OnResume method is assigning an empty data adapter to your listview.
Where are you populating your markers collection?
Also, you can call getListView and setListAdapter methods of the ListFragment class rather than finding the list with findViewById.
I have a BaseAdapter in that, I have a Button. When a user clicks on that button, I need to call a Service and I need to set the data to that button in onpostExecute()
public class MenuTagsAdapter extends BaseAdapter {
View v;
#Override
public int getCount() {
// TODO Auto-generated method stub
return BaseApp.getTagsAroundMeList().size();
}
#Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return position;
}
#Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater layoutInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = layoutInflater.inflate(R.layout.menutaglistitem, null);
TextView textViewName = (TextView) v
.findViewById(R.id.textViewName);
final Button buttonAction = (Button) v
.findViewById(R.id.buttonAction);
textViewName.setText("#"
+ BaseApp.getTagsAroundMeList().get(position).name);
buttonAction
.setText(BaseApp.getTagsAroundMeList().get(position).action);
buttonAction.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (buttonAction.getText().toString()
.equalsIgnoreCase("follow")) {
buttonAction.setBackgroundResource(R.drawable.followbutton);
if (appUtils.getNetworkInfo(AmgonnaHome.this)) {
new FollowInterestAsyTask().execute();
} else {
NetworkDialogClass.createDAlertDialog(
AmgonnaHome.this,
getString(R.string.network_error));
}
} else {
buttonAction.setBackgroundResource(R.drawable.unfollowbutton);
if (appUtils.getNetworkInfo(AmgonnaHome.this)) {
new UnfollowInterestAsyTask().execute();
} else {
NetworkDialogClass.createDAlertDialog(
AmgonnaHome.this,
getString(R.string.network_error));
}
}
}
});
return v;
}
}
public class FollowInterestAsyTask extends AsyncTask<Void, Void, Void> {
boolean progressDialogStatus = true;
#Override
protected void onPreExecute() {
progressDialog = ProgressDialog.show(AmgonnaHome.this,
"Please Wait", "Connecting to Server");
progressDialog.setOnCancelListener(new OnCancelListener() {
#Override
public void onCancel(DialogInterface dialog) {
progressDialogStatus = false;
}
});
}
#Override
protected Void doInBackground(Void... params) {
TaskUrl = BaseApp.baseUrl + BaseApp.followInterest;
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("user_id=" + amgonnaUserId);
// stringBuilder.append("&interestName="+);
stringBuilder.append("&interestName=");
ConnectionManager connectionManager = new ConnectionManager();
String response = connectionManager.setUpHttpPost(TaskUrl,
stringBuilder.toString());
if (response != null) {
try {
JSONObject jsonObject = new JSONObject(response);
errStatus = jsonObject.getInt("errStatus");
status = jsonObject.getString("status");
} catch (Exception e) {
// TODO: handle exception
}
}
return null;
}
#Override
protected void onPostExecute(Void result) {
if (progressDialogStatus) {
progressDialog.dismiss();
if (errStatus == 0) {
// here i need to set the status message to button on adapter list item
}
}
}
}
Just save the string you want to show in button in a variable.
eg :
String temp=btnText;
Then call your list adapter again.
And make a change in your getView() as
buttonAction.setText(temp);
*
*
My Problem is that each Activity in my App gets data from Web Service and if
it remains idle for some OS dialog pops up showing Force Close and OK
option. when i clicks force close it stops but when i click Ok button it remains
in Activity, but when i move to other activity no data is shown as it does not hit web service
to get data for that activity
So, how to handle this situation
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.coupon_layout);
context = this;
merchantName = (TextView) findViewById(R.id.CouponsMerchantName);
address = (TextView) findViewById(R.id.CouponsDetailAddress);
phone = (TextView) findViewById(R.id.CouponsDetailsPhone);
categoryImage = (ImageView) findViewById(R.id.CouponsCategoryImage01);
couponsListLayout = (ListView) findViewById(R.id.CouponsListLayout);
backButton = (Button) findViewById(R.id.CouponsBackButton);
backButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
finish();
}
});
try {
entry = Data.storeMecrchantDetailMain.get(0);
merchantName.setText(entry.getMerchantName());
address.setText(entry.getAddress());
phone.setText(entry.getPhone());
ImageLoader imageLoader = new ImageLoader(CouponsActivity.this);
String categoryImg = Data.URL_BASE + entry.getCategoryImg();
categoryImage.setTag(categoryImg);
imageLoader.DisplayImage(categoryImg, CouponsActivity.this,
categoryImage);
adapter = new CustomAdapterCoupons(this, entry.getCouponsList());
couponsListLayout.setAdapter(adapter);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
class CustomAdapterCoupons extends BaseAdapter {
/* Variable Declaration */
private Context context;
private List<CouponBean> list;
private CouponBean entry;
public com.a.util.ImageLoader imageLoader;
private LayoutInflater inflater;
public CustomAdapterCoupons(Context context, List<CouponBean> list) {
this.context = context;
this.list = list;
inflater = (LayoutInflater) CouponsActivity.this
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
imageLoader = new com.abc.util.ImageLoader(context);
}
public int getCount() {
// TODO Auto-generated method stub
return list.size();
}
public Object getItem(int position) {
// TODO Auto-generated method stub
return list.get(position);
}
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
public class ViewHolder {
public TextView couponName, couponCode, usageDescription,
expirationDate;
public ImageView couponImage;
}
public View getView(final int position, View convertView,
ViewGroup parent) {
// TODO Auto-generated method stub
ViewHolder holder = null;
entry = list.get(position);
if (convertView == null) {
convertView = inflater.inflate(R.layout.coupons_list_layout,
null);
holder = new ViewHolder();
holder.couponName = (TextView) convertView
.findViewById(R.id.CouponListCouponName);
holder.couponCode = (TextView) convertView
.findViewById(R.id.CouponListCouponCode);
holder.expirationDate = (TextView) convertView
.findViewById(R.id.CouponListDetailDate);
holder.usageDescription = (TextView) convertView
.findViewById(R.id.CouponListUsageDescription);
holder.couponImage = (ImageView) convertView
.findViewById(R.id.CouponListLeftImage);
convertView.setTag(holder);
// Set the display text
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.couponName.setText(entry.getCouponName());
holder.expirationDate.setText(context
.getString(R.string.Coupon_Expiration_Date)
+ "\n"
+ entry.getExpirationDate());
holder.usageDescription.setText(entry.getUsageDescription());
holder.couponCode.setText(entry.getCouponCode());
holder.couponImage.setTag(Data.URL_BASE_2 + entry.getCouponImage());
imageLoader.DisplayImage(Data.URL_BASE_2 + entry.getCouponImage(),
(Activity) context, holder.couponImage);
Log.v(Data.LOG3, "image" + entry.getCouponImage());
final Button savedMyCoupons = (Button) convertView
.findViewById(R.id.CouponListAddtoMyCouponButton);
if (entry.getSavedMyCoupons().equalsIgnoreCase("N")) {
savedMyCoupons.setText(context
.getString(R.string.Add_to_myCoupons));
savedMyCoupons.setBackgroundResource(R.drawable.done_btn);
savedMyCoupons.setTag(entry.getCouponId().toString());
savedMyCoupons.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
createProgressDialog();
new Loader()
.execute(savedMyCoupons.getTag().toString());
}
});
} else if (entry.getSavedMyCoupons().equalsIgnoreCase("Y")) {
savedMyCoupons.setText(context
.getString(R.string.Already_Added_to_my_coupons));
savedMyCoupons.setBackgroundColor(Color.WHITE);
savedMyCoupons.setTextColor(Color.BLACK);
}
// display the view corresponding to data at specified position
return convertView;
}
}
private void createProgressDialog() {
progressDialog = new ProgressDialog(context);
// progressDialog.setIcon(R.drawable.icon);
progressDialog.setTitle(R.string.Please_Wait);
progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
progressDialog.setIndeterminate(true);
progressDialog.setIndeterminateDrawable(context.getResources()
.getDrawable(R.anim.simple_animation));
progressDialog.setMessage(context.getString(R.string.Please_Wait));
progressDialog.show();
}
#Override
public void onResume() {
Log.v(Data.LOG, "On Resume");
super.onResume();
}
class Loader extends AsyncTask<String, String, String> {
Boolean value;
protected String doInBackground(String... arg0) {
try {
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(Data.URL_POST_DATA);
try {
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair("couponsubmit",
"submit"));
nameValuePairs.add(new BasicNameValuePair("sid",
Data.GET_SESSION_ID));
nameValuePairs.add(new BasicNameValuePair("api", "on"));
nameValuePairs.add(new BasicNameValuePair("couponid",
arg0[0]));
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
ResponseHandler<String> responseHandler = new BasicResponseHandler();
String responseBody = httpclient.execute(httppost,
responseHandler);
// String result = responseBody;
Log.v(Data.LOG1, "Response : " + responseBody);
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
} catch (Exception e) {
Log.e(Data.LOG, "" + e.getMessage());
e.printStackTrace();
}
LocateServices.getInstance().getStoreMerchantDetails(
entry.getMerchantID());
return null;
}
#Override
protected void onPostExecute(String result) {
// TODOAuto-generated method stub
super.onPostExecute(result);
handler.sendEmptyMessage(0);
}
private Handler handler = new Handler() {
#Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
entry = Data.storeMecrchantDetailMain.get(0);
adapter = new CustomAdapterCoupons(context,
entry.getCouponsList());
couponsListLayout.setAdapter(adapter);
progressDialog.dismiss();
}
};
}
}
Thanks for any help.
*
The dialog you are talking about is called ANR(Activity Not Responding) dialog, and there's no any method by which you can get the dialog to go away, and you should not try to remove it either.
You can however, call a new thread and run the methods to get data from web in that separate thread, instead of the UI thread.
Another method could be to start the fetching method after a second. The code example for this could be like this:
new Handler().postDelayed(new Runnable() {
public void run() {
//Your method to get data from web here
}
}, 1000); //delay in milliseconds
The above code will delay the fetching method by a second, so that the ANR dialog can be tricked away. However you should use a separate thread instead of this for better result.
Do your fetching in the background, your users will be happy. I use AsyncTask.
Try using Async Task function
Declare the function using
new AsynBackground().execute(u);
and implement the function as follows
private class AsynBackground extends AsyncTask<String, Void, Void>
{
#Override
protected Void doInBackground(String... params) {
// TODO Auto-generated method stub
fetchDistancesFromGoogle(params[0]);
return null;
}
}