ListItems doubles in number(duplicated) in Custom ListView in android - android

I am using a custom ListView which gets doubled in number(duplicate listItems) when I go to previous activity and again come to that ListViewActivity.
I can see where the problem occurs. When I go to the ListViewActivity for the first time everything is fine where the listitems are added to the ArrayList and the adapter is set. But when I go to the previous activity and come again to the ListViewActivity, the previously set listitems are still present in the Adapter and again the listitems are set when the process goes through setAdapter() which is causing the duplication of listitems.
I have came across many solutions like using notifyDataSetChanged(), clearing the ArrayList, setAdapter(null), etc. None of these solutions helped me.
I guess the solution is clearing the Adapterand the ArrayList and refreshing the Adapter. But I don't know how and where exactly to do it.
Here is my code:
This is the data recieving class in the LoadingActivity.java
private class CategoriesAsyncTask extends AsyncTask<String,Integer,Double>{
String res="";
String curState ="";
String httppoststr="";
boolean isNxtActivity=false;
#Override
protected Double doInBackground(String... params) {
// TODO Auto-generated method stub
postData(params[0]);
return null;
}
protected void onPostExecute(Double Result)
{
if(isNxtActivity)
{
Intent intent = new Intent(LoadingActivity.this, ListItemsActivity.class);
if(curState.equals(Constants.STATE_GET_STOCK_ITEMS))
{
intent.putStringArrayListExtra(Constants.STOCK_ITEMS_LIST, listOfItems);
intent.putExtra("curState", Constants.STATE_GET_STOCK_ITEMS);
intent.putExtra(Constants.CATEGORY_ID, categoryId);
intent.putExtra(Constants.CUSTOMER_ID, customerId);
LoadingActivity.this.startActivity(intent);
}
}
}
public void postData(String ValueIWantToSend) {
// Create a new HttpClient and Post Header
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(Constants.GatewayUrl);
try
{
JSONObject json = new JSONObject(ValueIWantToSend);
curState = json.getString("curState");
StringEntity se = new StringEntity(ValueIWantToSend);
httppost.setEntity(se);
httppost.setHeader("Accept", "application/json");
httppost.setHeader("Content-type", "application/json");
httppoststr =httppost.toString();
// Execute HTTP Post Request
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
res = EntityUtils.toString(entity, "UTF-8");
JSONObject jsonobj = new JSONObject(res);
String state = jsonobj.getString(Constants.STATE);
if(Constants.RESPONSE_SUCCESS.equals(state.toLowerCase()))
{
isNxtActivity =true;
if(curState.equals(Constants.STATE_GET_STOCK_ITEMS))
{
JSONArray itemsListJsonArray=new JSONArray();
itemsListJsonArray=jsonobj.getJSONArray(Constants.STOCK_ITEMS_LIST);
for(int i=0;i<itemsListJsonArray.length();i++)
{
String itemslist=itemsListJsonArray.getString(i);
listOfItems.add(itemslist.toString());
}
}
}
}
catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
catch (JSONException e) {
e.printStackTrace();
}
}
}
ListViewActivity.java
private String[] arrayOfNames;
private String[] arrayOfImageUrls;
ArrayList<String> listOfNames = new ArrayList<String>();
ArrayList<String> listOfImageUrls = new ArrayList<String>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list_items);
itemsList=(ListView) findViewById(R.id.itemsList);
Bundle extras = getIntent().getExtras();
listOfItems = extras.getStringArrayList(Constants.STOCK_ITEMS_LIST); //The duplication occurs here while getting the data from the LoadingActivity when visiting this activity for the second time.
arrayOfNames = new String[listOfNames.size()];
for(int i=0;i<listOfNames.size();i++)
{
arrayOfNames[i]=listOfNames.get(i);
}
arrayOfImageUrls = new String[listOfImageUrls.size()];
for(int i=0;i<listOfImageUrls.size();i++)
{
arrayOfImageUrls[i]=listOfImageUrls.get(i);
}
listItemadapter = new CustomListItemsAdapter(this, arrayOfNames, arrayOfImageUrls);
itemsList.setAdapter(listItemadapter);
}
CustomAdapter.java
public class CustomListItemsAdapter extends BaseAdapter{
private Context context;
private LayoutInflater inflater;
private String[] arrayOfNames;
public CustomListItemsAdapter(ListItemsActivity listItemsActivity, String[] itemsName) {
// TODO Auto-generated constructor stub
context=listItemsActivity;
arrayOfNames = itemsName;
inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return arrayOfNames.length;
}
#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;
}
public static class ViewHolder
{
private TextView itemName;
private ImageView itemImage;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if(convertView==null)
{
holder=new ViewHolder();
convertView = inflater.inflate(R.layout.list_item_content, parent, false);
holder.itemName = (TextView) convertView.findViewById(R.id.itemName);
holder.itemImage = (ImageView) convertView.findViewById(R.id.itemImage);
convertView.setTag(holder);
}
else
{
holder = (ViewHolder) convertView.getTag();
}
holder.itemName.setText(arrayOfNames[position]);
StrictMode.ThreadPolicy policy = new
StrictMode.ThreadPolicy.Builder()
.permitAll().build();
StrictMode.setThreadPolicy(policy);
ListItemsAsyncTask listAsync = new ListItemsAsyncTask();
Drawable drawableIcon = listAsync.loadImageFromServer(arrayOfImageUrls[position]);
holder.itemImage.setImageDrawable(drawableIcon);
return convertView;
}
private class ListItemsAsyncTask extends AsyncTask<String, Integer, Double> {
String httpPostStr, res;
Boolean NextActivity = false;
public Drawable loadImageFromServer(String url)
{
try {
InputStream is = (InputStream) new URL(url).getContent();
Drawable drawable = Drawable.createFromStream(is, "src name");
return drawable;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
#Override
protected Double doInBackground(String... params) {
return null;
}
}
Any Suggestions???
UPDATE: I have found the problem behind this duplication. The second time when I come to the ListViewActivity the duplication occurs in the Bundle from which I get the data for the ListView and its contents.
Now I need a solution to stop the duplication in the Bundle. I have mentioned the duplication occuring line with a comment in ListViewActivity.java

Call the function setAdapter() only once in onCreate() , because onCreate() is called only when the activity first starts , second time when you start the activity onCreate() is not called , but if you destroy the activity , then onCreate() will be called again , make sure you are not destroying the activity .

probably you are loading list in onResume and you are adding items to list attached to adapter and here you have duplicate each time.
Proper way is:
load data in onResume, make sure you are not adding duplicates to list, or clear list before adding data. then after fill list - check if adapter was initialised and attached if already initialised then add data to list and simple make on adapter .notifyDataSetChanged() if not initialised then initialise it with attaching your list to it.
Make attention when you attached list to adapter then you cannot change pointer to your list variable:
yourList = downloadedList; // Wrong way you will override the pointer to list in adapter
must be something like:
yourList.clear();
yourList.addAll(downloadedList); // Correct way
adapter.notifyDataSetChanged();

Related

How do I pass id of listview item I got from server to another activity onclick?

I got the data from server to list view successfully with some online help. What I wanted is to go to another activity and get the "id" of the list view item and display it.
I have been trying a lot to figure this out but haven't succeeded.
My mainactivity.java file
public class MainActivity extends AppCompatActivity {
ListView listView;
Button button;
// Server Http URL
String HTTP_URL = "http://192.168.100.48/listview/index.php";
// String to hold complete JSON response object.
String FinalJSonObject ;
ProgressBar progressBar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Assign ID's to ListView.
listView = (ListView) findViewById(R.id.listView1);
button = (Button)findViewById(R.id.button);
progressBar = (ProgressBar)findViewById(R.id.ProgressBar1);
// Adding click listener to button.
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//Showing progress bar just after button click.
progressBar.setVisibility(View.VISIBLE);
// Creating StringRequest and set the JSON server URL in here.
StringRequest stringRequest = new StringRequest(HTTP_URL,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
// After done Loading store JSON response in FinalJSonObject string variable.
FinalJSonObject = response ;
// Calling method to parse JSON object.
new ParseJSonDataClass(MainActivity.this).execute();
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
// Showing error message if something goes wrong.
Toast.makeText(MainActivity.this,error.getMessage(),Toast.LENGTH_LONG).show();
}
});
// Creating String Request Object.
RequestQueue requestQueue = Volley.newRequestQueue(MainActivity.this);
// Passing String request into RequestQueue.
requestQueue.add(stringRequest);
}
});
}
// Creating method to parse JSON object.
private class ParseJSonDataClass extends AsyncTask<Void, Void, Void> {
public Context context;
// Creating List of Subject class.
List<Subject> CustomSubjectNamesList;
public ParseJSonDataClass(Context context) {
this.context = context;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected Void doInBackground(Void... arg0) {
try {
// Checking whether FinalJSonObject is not equals to null.
if (FinalJSonObject != null) {
// Creating and setting up JSON array as null.
JSONArray jsonArray = null;
try {
// Adding JSON response object into JSON array.
jsonArray = new JSONArray(FinalJSonObject);
// Creating JSON Object.
JSONObject jsonObject;
// Creating Subject class object.
Subject subject;
// Defining CustomSubjectNamesList AS Array List.
CustomSubjectNamesList = new ArrayList<Subject>();
for (int i = 0; i < jsonArray.length(); i++) {
subject = new Subject();
jsonObject = jsonArray.getJSONObject(i);
//Storing ID into subject list.
subject.Subject_ID = jsonObject.getString("id");
//Storing Subject name in subject list.
subject.Subject_Name = jsonObject.getString("subject_Name");
// Adding subject list object into CustomSubjectNamesList.
CustomSubjectNamesList.add(subject);
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void result)
{
// After all done loading set complete CustomSubjectNamesList with application context to ListView adapter.
ListViewAdapter adapter = new ListViewAdapter(CustomSubjectNamesList, context);
// Setting up all data into ListView.
listView.setAdapter(adapter);
// Hiding progress bar after all JSON loading done.
progressBar.setVisibility(View.GONE);
}
}
}
My Listviewadapter.java file
public class ListViewAdapter extends BaseAdapter
{
Context context;
List<Subject> TempSubjectList;
public ListViewAdapter(List<Subject> listValue, Context context)
{
this.context = context;
this.TempSubjectList = listValue;
}
#Override
public int getCount()
{
return this.TempSubjectList.size();
}
#Override
public Object getItem(int position)
{
return this.TempSubjectList.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.IdTextView = (TextView)convertView.findViewById(R.id.textviewID);
viewItem.NameTextView = (TextView)convertView.findViewById(R.id.textviewSubjectName);
convertView.setTag(viewItem);
}
else
{
viewItem = (ViewItem) convertView.getTag();
}
viewItem.IdTextView.setText(TempSubjectList.get(position).Subject_ID);
viewItem.NameTextView.setText(TempSubjectList.get(position).Subject_Name);
return convertView;
}
}
class ViewItem {
TextView IdTextView;
TextView NameTextView;
}
And of course, my subject.java file
public class Subject {
public String Subject_ID;
public String Subject_Name;
}
IMAGE - It successfully shows the data from server. But I haven't figured it out how to make what I want to do when I click the item.
So yes, that's what's taking my sleep and peace.
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1,
int position, long id) {
Intent intent = new Intent(MainActivity.this, AnotherActivity.class);
intent.putExtra("ID",CustomSubjectNamesList.get(position).Subject_ID);
startActivity(intent);
}
});
And From Another Activity
First, get the intent which has started your activity using the getIntent() method:
Intent intent = getIntent();
If your extra data is represented as strings, then you can use intent.getStringExtra(String name) method. In your case:
Intent intent = getIntent();
String id = intent.getStringExtra("ID");
you can send a string or an integer or simply any object that implements Serializable to another activity using intent.putExtra()
listView.setOnItemClickListener(new AdapaterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1,
int position, long id) {
Intent intent = new Intent(MainActivity.this, AnotherActivity.class);
intent.putExtra("id",CustomSubjectNamesList.get(position).Subject_ID;
startActivity(intent);
}
});
And in your new activity receive that info you just sent using getIntent.getIntExtra("id") or getIntent.getStringExtra(). or using it's other methods based on what you have sent.

Android Recycle View inside fragment show "No adapter attached; skipping layout "

if i write this code in a class extends AppCompatActivity it
works but in a fragment class i don't know why it doesn't work .
in the activity that has this fragment i use another adapter
to show products with the same code and it works
public class Categroy extends Fragment{
// CONNECTION_TIMEOUT and READ_TIMEOUT are in milliseconds
public static final int CONNECTION_TIMEOUT = 10000;
public static final int READ_TIMEOUT = 15000;
public RecyclerView mRVcategoryList;
public AdapterCategory mAdapter;
private String myurl="http://10.0.3.2/mobilaApp/category.php";
// private String categoryurl="http://10.0.3.2/mobilaApp/category.php";
public LinearLayoutManager layoutManager;
List<DataCategory> data=new ArrayList<>();
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// execute asyncLogin
new AsyncLogin().execute();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_categroy, container, false);
RecyclerView recyclerView = (RecyclerView) rootView.findViewById(R.id.rvcat);
// 2. set layoutManger
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
// 3. create an adapter
AdapterCategory mAdapter = new AdapterCategory(getActivity().getApplicationContext(), data);
// 4. set adapter
recyclerView.setAdapter(mAdapter);
recyclerView.setItemAnimator(new DefaultItemAnimator());
return rootView;
}
private class AsyncLogin extends AsyncTask<String, String, String> {
ProgressDialog pdLoading = new ProgressDialog(getActivity());
HttpURLConnection conn;
URL url = null;
#Override
protected void onPreExecute() {
super.onPreExecute();
//this method will be running on UI thread
pdLoading.setMessage("\tLoading...");
pdLoading.setCancelable(false);
pdLoading.show();
}
#Override
protected String doInBackground(String... params) {
try {
// Enter URL address where your json file resides
// Even you can make call to php file which returns json data
url = new URL(myurl);
// urlcat = new URL(categoryurl);
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return e.toString();
}
try {
// Setup HttpURLConnection class to send and receive data from php and mysql
conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(READ_TIMEOUT);
conn.setConnectTimeout(CONNECTION_TIMEOUT);
conn.setRequestMethod("GET");
// setDoOutput to true as we recieve data from json file
conn.setDoOutput(true);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
return e1.toString();
}
try {
int response_code = conn.getResponseCode();
// Check if successful connection made
if (response_code == HttpURLConnection.HTTP_OK) {
// Read data sent from server
InputStream input = conn.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(input));
StringBuilder result = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
result.append(line);
}
// Pass data to onPostExecute method
return (result.toString());
} else {
return ("unsuccessful");
}
} catch (IOException e) {
e.printStackTrace();
return e.toString();
} finally {
conn.disconnect();
}
}
#Override
protected void onPostExecute(String result) {
//this method will be running on UI thread
// dississ dialog pdLoading.dismiss();
pdLoading.dismiss();
try {
JSONArray jArray = new JSONArray(result);
// Extract data from json and store into ArrayList as class objects
for(int i=0;i<jArray.length();i++){
JSONObject json_data = jArray.getJSONObject(i);
DataCategory categorydata = new DataCategory();
categorydata.name_cat= json_data.getString("name_cat");
data.add(categorydata);
}
mRVcategoryList = (RecyclerView)getActivity(). findViewById(R.id.rvcat);
mAdapter = new AdapterCategory(getActivity().getApplicationContext(), data);
mRVcategoryList.setAdapter(mAdapter);
mRVcategoryList.setLayoutManager(new LinearLayoutManager(getActivity().getApplicationContext()));
} catch (JSONException e) {
Toast.makeText(getActivity().getApplicationContext(), e.toString(), Toast.LENGTH_LONG).show();
}
}
}
}
/* if i write this code in a class extends AppCompatActivity it
works but in a fragment class i don't know why it doesn't work .
in the activity that has this fragment i use another adapter
to show products with the same code and it works
*/
Adapter is here
public AdapterCategory(Context context, List<DataCategory> data){
this.context=context;
inflater= LayoutInflater.from(context);
this.data=data;
}
// Inflate the layout when viewholder created
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view=inflater.inflate(R.layout.categoryrow, parent,false);
MyHolder holder=new MyHolder(view);
return holder;
}
// Bind data
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
// Get current position of item in recyclerview to bind data and assign values from list
MyHolder myHolder= (MyHolder) holder;
DataCategory current=data.get(position);
myHolder.namecat.setText(current.name_cat);
}
// return total item from List
#Override
public int getItemCount() {
return data.size();
}
class MyHolder extends RecyclerView.ViewHolder{
TextView namecat;
// TextView textPrice;
// create constructor to get widget reference
public MyHolder(View itemView) {
super(itemView);
namecat= (TextView) itemView.findViewById(R.id.category_name);
}
}
}
Set layoutManager to your recyclerView using getContext() instead of getActivity() and it will work.
mListLayoutManager=new LinearLayoutManager(getContext());
recyclerView.setLayoutManager(mListLayoutManager);
Thank you all
the problem was to replace getActivity() by getView() onpostexecute
mRVFishPrice = (RecyclerView)getView().findViewById(R.id.fishPriceList);
mAdapter = new AdapterFish(getActivity(), data);
mRVFishPrice.setAdapter(mAdapter);
mRVFishPrice.setLayoutManager(new LinearLayoutManager(getActivity()));

android adapter from async task

In one of my app, I need to use AsyncTask. I need to get an image URL from an HTTP site. I have done this in the doInBackground method. I am getting the URL of that image as a string.
publishProgress(thumb);//thumb is string
then in
#Override
protected void onProgressUpdate(String... values) {
super.onProgressUpdate(values);
sample = new ArrayList<String>();
System.out.println("this is on progress..."+values[0]);
sample.add(values[0]);
GridviewAdapter_old go=new GridviewAdapter_old(getActivity(), sample);
gv.setAdapter(go);
// gv.setAdapter(ga);
}
public class GridviewAdapter_old extends BaseAdapter
{
private ArrayList<String> listCountry;
private Activity activity;
public GridviewAdapter_old(Activity activity, ArrayList<String> listCountry) {
super();
// this.listCountry = listCountry;
this.listCountry = new ArrayList<String>();
this.listCountry = listCountry;
// this.listFlag = listFlag;
this.activity = activity;
System.out.println("this is contry name " + this.listCountry);
// System.out.println("this is img name " + this.listFlag);
// System.out.println();
}
#Override
public int getCount() {
// TODO Auto-generated method stub
System.out.println("len " + listCountry.size());
// return listCountry.size();
return listCountry.size();
}
#Override
public String getItem(int position) {
// TODO Auto-generated method stub
return listCountry.get(position);
}
#Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return 0;
}
public static class ViewHolder {
public ImageView imgViewFlag;
// public TextView txtViewTitle;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
ViewHolder view;
LayoutInflater inflator = activity.getLayoutInflater();
if (convertView == null) {
view = new ViewHolder();
convertView = inflator.inflate(R.layout.test, null);
view.imgViewFlag = (ImageView) convertView
.findViewById(R.id.grid_item_image);
// view.imgViewFlag.setBackgroundResource(R.drawable.view_default);
convertView.setTag(view);
}
else {
view = (ViewHolder) convertView.getTag();
}
try {
URL myUrl = new URL(listCountry.get(0));
InputStream inputStream = (InputStream) myUrl.getContent();
Drawable drawable = Drawable.createFromStream(inputStream, null);
view.imgViewFlag.setImageDrawable(drawable);
} catch (Exception e) {
System.out.println(e.getMessage());
}
/*
* Bitmap imageBitmap = null; //System.gc(); try { URL imageURL = new
* URL(listCountry.get(0));
* System.out.println("this is in last portion..."
* +listCountry.get(position)); imageBitmap =
* BitmapFactory.decodeStream(imageURL.openStream());
* view.imgViewFlag.setImageBitmap(imageBitmap); //
* view.txtViewTitle.setText(listCountry.get(position)); //
* view.imgViewFlag.setImageResource(listFlag.get(position));
*
* } catch (Exception e) { System.out.println("this is error " +
* e.getMessage()); }
*/
return convertView;
}
}
The problem is:
I am not getting an image from the URL (that is getting from thumb (publishProgress(thumb);)
I am not getting the multiple images.
you are only getting one in your list because every time you call onProgressUpdate you create a new list.
You dont want to use onProgressUpdate to populate your list, that would be an insane amount of overhead. Instead you want to create your list inside your doInBackground then pass that list to your onPostExecute then put the new list to the adapter and call notifyDatasetChanged on the adapter to refresh the list.
in short, create the adapter (class wide variable), create an ArrayList (class wide variable) and everytime a change is made the the list all you have to do is call notifyDatasetCHanged on the adapter
ArrayList<String> list = new ArrayList<String();
ArrayAdapter adapter;
public class AsyncTask.....
#Override
protected Void doInBackground(Void... params){
...
list.add(stuff);
}
#Override
protected Void onPostExecute(Void params){
adapter.notifyDatasetChanged();
}

Android OS dialog Box Which shows Force Close and ok when Application remains in idle state for some Time

*
*
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;
}
}

Suggestions to improve Activity Performance?

friends,
i am using following global variables in my activity
private String Session_ID;
private String uid;
// menu item starts
private final int Trash = 0x003;
private final int More = 0x005;
private final int SignOut = 0x006;
private final int SignIn = 0x007;
//menu item ends
private EfficientAdapter adap;
private String[] Msg_id;
private String[] Msg_body;
private String[] Sent_by;
private String[] Sent_on;
private String[] Is_my_message;
private String[] Photo_thumbnail;
private String[] Photo_full_path;
private String Conversation_id;
ProgressBar progressBar;
Button getMoreButton;
boolean callComplete = false;
private Handler mHandler = new Handler();
private int PageSize = Constants.pageSizeForMessages;
Object serviceData = null;
private String ConversationName;
private Uri selectedImage;
public class EfficientAdapter extends BaseAdapter implements Filterable {
private LayoutInflater mInflater;
private Context context;
public EfficientAdapter(Context context) {
mInflater = LayoutInflater.from(context);
this.context = context;
}
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder;
convertView = mInflater.inflate(R.layout.adaptor_contentmessagedetail, null);
holder = new ViewHolder();
holder.ImgPhoto = (ImageView)convertView.findViewById(R.id.ImgPhoto);
holder.lblMsgSentBy = (TextView) convertView.findViewById(R.id.lblSentBy);
holder.lblMsgBody = (TextView) convertView.findViewById(R.id.lblMessageBody);
holder.lblMsgSentOn = (TextView) convertView.findViewById(R.id.lblSentOn);
convertView.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if (!((MessageDetail)v.getContext()).isConnected()) {
Constants.DisplayMessage(v.getContext(),
Constants.CONNECTION_ERROR_MESSAGE);
return;
}
if(!Photo_full_path[position].equals(""))
{
String str= Photo_full_path[position].substring(Photo_full_path[position].length() - 3);
if(str.equals("pdf"))
{
}else
{
Intent myIntent = new Intent(v.getContext(), ViewSingleImage.class);
Bundle b = new Bundle();
b.putString("single_image_path", Photo_full_path[position] );
myIntent.putExtras(b);
v.getContext().startActivity(myIntent);
}
}
}
});
convertView.setTag(holder);
// Bind the data efficiently with the holder.
if(Is_my_message[position].equals("1"))
holder.lblMsgSentBy.setTextColor(Color.BLACK);
else
holder.lblMsgSentBy.setTextColor(Color.rgb(255, 107, 1));
SimpleDateFormat fromUser = new SimpleDateFormat(Constants.SERVICE_DATE_FORMAT);
java.text.DateFormat df=new SimpleDateFormat(Constants.DATE_FORMAT);
Date dt=new Date();
try
{
dt = fromUser.parse(Sent_on[position]);
} catch (java.text.ParseException e) {
e.printStackTrace();
}
// display photo
if(!Photo_thumbnail[position].equals(""))
{
// resize it
holder.ImgPhoto.setImageBitmap(DisplayLiveImage(Photo_thumbnail[position]));
}else
{
holder.ImgPhoto.setVisibility(View.GONE);
}
// display photo
holder.lblMsgSentBy.setText(Constants.GetSpecialCharacters(Sent_by[position]));
holder.lblMsgBody.setText(Constants.GetSpecialCharacters(Msg_body[position]));
holder.lblMsgSentOn.setText(df.format(dt));
return convertView;
}
class ViewHolder {
ImageView ImgPhoto;
TextView lblMsgSentBy;
TextView lblMsgBody;
TextView lblMsgSentOn;
}
#Override
public Filter getFilter() {
// TODO Auto-generated method stub
return null;
}
#Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return 0;
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return Msg_id.length;
}
#Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return Msg_id[position];
}
}
public Bitmap DisplayLiveImage(String ImageSrc)
{
Bitmap bm;
try {
URL aURL = new URL(ImageSrc);
URLConnection conn = aURL.openConnection();
conn.connect();
InputStream is = null;
try
{
is= conn.getInputStream();
}catch(IOException e)
{
return null;
}
BufferedInputStream bis = new BufferedInputStream(is);
bm = BitmapFactory.decodeStream(bis);
bis.close();
is.close();
} catch (IOException e) {
return null;
}
return bm;
}
i have made them global in activity because i need them all in more than 1 functions
now my question is how to improve performance of my activity it is too slow
should i make them static or what?
any help would be appreciated.
Your global variables are almost certainly not the cause of your poor performance. Unless you're accessing them a million times, it must be something else. If you tell us what exactly is performing slower than you would expect and post the relevant code, we might be able to help.
You have a LOT of code in your getView() method. this method gets called every single time a new view gets displayed. So when the listview is created, it's called N times where N being the number of list elements that are seen. Then when you scroll, every time a new element comes onto the screen, getView() gets called again. Even if you then scroll back up, it calls getView() again.
You need to refactor your code that doesn't need to be run every time a view is created out of the view.
it is recommended to cache images and dont bring them all again and again from internet.
so my case while using custom adapter and scrolling it was again and again loading images from internet
which was causing poor performance.
and memory leakage problem too.
so what i did i followed following tutorial to load live images and my problem resolved
Answer: LazyList
http://mobilebitworks.wordpress.com/2010/11/05/android-listview-and-dynamically-loading-images-from-the-web

Categories

Resources