I have customized the code of EndlessAdapter in my app but one mistake done by me as this Endless Adapter always download data in the background instead it should download the same after user scroll downs the list and I unable to find the same mistake in our project. Due to this mistake my app sometimes returns OutOfMemoryException which is not acceptable.
Please suggest me any solution regarding the same.
Code:
*MyEndlessAdapter:*
class DemoAdapterCat extends EndlessAdapter {
private RotateAnimation rotate=null;
ArrayList<String> tempListNamesCat = new ArrayList<String>();
ArrayList<String> tempListImagesCat = new ArrayList<String>();
ArrayList<String> tempListYearCat1 = new ArrayList<String>();
ArrayList<String> tempListYearCat2 = new ArrayList<String>();
ArrayList<String> tempListmpgCat1 = new ArrayList<String>();
ArrayList<String> tempListmpgCat2 = new ArrayList<String>();
ArrayList<String> tempListpriceCat1 = new ArrayList<String>();
ArrayList<String> tempListpriceCat2 = new ArrayList<String>();
ArrayList<String> tempListRatingCat1 = new ArrayList<String>();
ArrayList<String> tempListRatingCat2 = new ArrayList<String>();
DemoAdapterCat() {
super(new CategoryListLazyAdapter(ResearchList.this, countriesSubCat, imagesSubCat, YearSubCat1,YearSubCat2, mpgSubCat1,mpgSubCat2, priceSubCat1,priceSubCat2, ratingSubCat1, ratingSubCat2));
Utility util = new Utility();
util.setListViewHeightBasedOnChildren(lvCategory);
rotate=new RotateAnimation(0f, 360f, Animation.RELATIVE_TO_SELF,
0.5f, Animation.RELATIVE_TO_SELF,
0.5f);
rotate.setDuration(600);
rotate.setRepeatMode(Animation.RESTART);
rotate.setRepeatCount(Animation.INFINITE);
}
/*
#Override
public int getCount()
{
//return brandList.getDisplayNames().size();
return countriesSubCat.size();
}*/
#Override
protected View getPendingView(ViewGroup parent) {
row=getLayoutInflater().inflate(R.layout.categorylist, null);
child=row.findViewById(R.id.tv_CategoryItem_Name);
child.setVisibility(View.GONE);
child = row.findViewById(R.id.tv_CategoryItem_MPG1);
child.setVisibility(View.GONE);
child = row.findViewById(R.id.tv_CategoryItem_MPG2);
child.setVisibility(View.GONE);
child = row.findViewById(R.id.tv_CategoryItem_Price1);
child.setVisibility(View.GONE);
child = row.findViewById(R.id.tv_CategoryItem_Price2);
child.setVisibility(View.GONE);
child = row.findViewById(R.id.tv_CategoryItem_Rating1);
child.setVisibility(View.GONE);
child = row.findViewById(R.id.tv_CategoryItem_Rating2);
child.setVisibility(View.GONE);
child = row.findViewById(R.id.tv_CategoryItem_Year1);
child.setVisibility(View.GONE);
child = row.findViewById(R.id.tv_CategoryItem_Year2);
child.setVisibility(View.GONE);
/*child = row.findViewById(R.id.img_CategoryItem);
child.setVisibility(View.GONE);
child = row.findViewById(R.id.img_CategoryItem_Arrow);
child.setVisibility(View.GONE);*/
/*child = row.findViewById(R.id.linear_main_MPG);
child.setVisibility(View.GONE);*/
child=row.findViewById(R.id.throbber);
child.setVisibility(View.VISIBLE);
child.startAnimation(rotate);
return(row);
}
#Override
protected boolean cacheInBackground() {
SystemClock.sleep(10000);
tempListNamesCat.clear();
tempListImagesCat.clear();
tempListmpgCat1.clear();
tempListmpgCat2.clear();
tempListpriceCat1.clear();
tempListpriceCat2.clear();
tempListYearCat1.clear();
tempListYearCat2.clear();
tempListRatingCat1.clear();
tempListRatingCat2.clear();
int lastOffset = getLastOffset();
if(lastOffset < LIST_SIZE){
int limit = lastOffset + BATCH_SIZE;
for(int i=(lastOffset+1); (i<=limit && i<LIST_SIZE); i++){
tempListNamesCat.add(coll.getDisplayNames().get(i));
tempListImagesCat.add(coll.getImages().get(i));
tempListmpgCat1.add(coll.getMpg().get(i));
tempListmpgCat2.add(coll.getMpg().get(i+1));
tempListpriceCat1.add(coll.getPrice().get(i));
tempListpriceCat2.add(coll.getPrice().get(i+1));
tempListRatingCat1.add(coll.getRating().get(i));
tempListRatingCat2.add(coll.getRating().get(i+1));
tempListYearCat1.add(coll.getYears().get(i));
tempListYearCat2.add(coll.getYears().get(i+1));
}
setLastOffset(limit);
if(limit<LIST_SIZE){
//return true;
return(getWrappedAdapter().getCount()<coll.getDisplayNames().size());
} else {
return false;
}
} else {
return false;
}
}
#Override
protected void appendCachedData() {
#SuppressWarnings("unchecked")
//Activity activity = this;
//ArrayAdapter<String> arrAdapterNew = (ArrayAdapter<String>)getWrappedAdapter();
CategoryListLazyAdapter arrAdapterNewCategory = (CategoryListLazyAdapter)getWrappedAdapter();
//int listLen = tempList.size();
// int listLen = tempListNames.size();
countriesSubCat.addAll(tempListNamesCat);
imagesSubCat.addAll(tempListImagesCat);
mpgSubCat1.addAll(tempListmpgCat1);
mpgSubCat2.addAll(tempListmpgCat2);
priceSubCat1.addAll(tempListpriceCat1);
priceSubCat2.addAll(tempListpriceCat2);
ratingSubCat1.addAll(tempListRatingCat1);
ratingSubCat2.addAll(tempListRatingCat2);
YearSubCat1.addAll(tempListYearCat1);
YearSubCat2.addAll(tempListYearCat2);
arrAdapterNewCategory.notifyDataSetChanged();
Utility util = new Utility();
util.setListViewHeightBasedOnChildren(lvCategory);
/* for(int i=0; i<listLen; i++){
// arrAdapterNew.add(tempList.get(i));
}*/
}
}
Set Demoadapter to the list:
public void setValuesInCategoryChildSortByAZ(String url,final String filter, final String from, final String to)
{
if(isOnline())
{
final ProgressDialog dialog = ProgressDialog.show(
ResearchList.this, "Research List ",
"Please wait... ", true);
final Handler handler = new Handler() {
public void handleMessage(Message msg) {
// System.out.println("The id after Save:"+id.get(0).toString());
// catagory.addAll(keyword_vector1);
linear_Category_Child.setVisibility(View.GONE);
linear_Category_Child_Child.setVisibility(View.VISIBLE);
//tv_Child_Header.setText("Volvo");
/*adapter = new CategoryListLazyAdapter(
ResearchList.this);
lvCategory.setAdapter(adapter);*/
demoAdapterCat.notifyDataSetChanged();
Utility util = new Utility();
util.setListViewHeightBasedOnChildren(lvCategory);
dialog.dismiss();
}
};
final Thread checkUpdate = new Thread() {
public void run() {
try {
String sortEncode = URLEncoder.encode("alpha");
String filterEncode = URLEncoder.encode(filter);
String clientEncode = URLEncoder.encode("10030812");
String fromEncode = URLEncoder.encode(from);
String toEncode = URLEncoder.encode(to);
String catUrl = "/v1/vehicles/get-make-models.json?sort="+sortEncode+"&filter="+filterEncode+"&client-id="+clientEncode+"&from="+fromEncode;
genSig = new GetSignature(catUrl, "acura");
try {
signature = genSig.getUrlFromString();
} catch (InvalidKeyException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (NoSuchAlgorithmException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
// jsonString =
// getJsonSring("http://api.highgearmedia.com/v1/vehicles/get-models.json?make=acura&client-id=10030812&signature=LWQbdAlJVxlXZ1VO2mfqAA==");
//String signatureEncode = URLEncoder.encode(signature);
String urlEncode = URLEncoder.encode(catUrl+"&signature="+signature);
jsonString = getJsonSring("http://apibeta.highgearmedia.com"+catUrl+"&signature="+signature);
System.out.println("The json category:===>"+jsonString);
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (URISyntaxException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
JsonParse json = new JsonParse(jsonString);
json.parseCat();
handler.sendEmptyMessage(0);
}
};
checkUpdate.start();
}else
{
AlertDialog.Builder builder = new Builder(ResearchList.this);
builder.setTitle("Attention!");
builder.setMessage("Network Connection unavailable.");
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
}
});
builder.create().show();
}
}
Thanks in advance.
I unable to find the same mistake in our project
The EndlessAdapter sample app is here: https://github.com/commonsguy/cwac-endless/tree/master/demo.
If you look at that sample app, you will notice that it does not fork any threads.
If you read the EndlessAdapter documentation, you will see:
Your EndlessAdapter subclass also needs to implement cacheInBackground(). This method will be called from a background thread, and it needs to download more data that will eventually be added to the ListAdapter you used in the constructor. While the demo application simply sleeps for 10 seconds, a real application might make a Web service call or otherwise load in more data.
Since this method is called on a background thread, you do not need to fork your own thread. However, at the same time, do not try to update the UI directly.
So, change your project to not fork your own thread, but instead do your work in cacheInBackground() to retrieve and add the next batch of data.
If that approach does not fit the way your app needs to run, that is fine, but you may have difficulty in using EndlessAdapter.
Related
i am working on a ecommerce app and i have a list where list of items will be there. Just like product name, price, discounted value etc fetched from database.
i am using ListView to show products where every item have there seprate Menu_ID. Whenever i click on list item following code is run where i use putExtra to open speciefic menu_id item details.
public void onItemClick(AdapterView<?> arg0, View arg1, int position,
long arg3) {
// TODO Auto-generated method stub
// go to menu detail page
Intent iDetail = new Intent(ActivityMenuList.this, ActivityMenuDetail.class);
iDetail.putExtra("menu_id", Menu_ID.get(position));
startActivity(iDetail);
}
and new activity will be open with product detail where i display add to cart button whenever i click on add to cart button item display in cart activity.
code is like
public void inputDialog() {
// open database first
try {
dbhelper.openDataBase();
} catch (SQLException sqle) {
throw sqle;
}
AlertDialog.Builder alert = new AlertDialog.Builder(this);
alert.setTitle(R.string.order);
alert.setMessage(R.string.number_order);
alert.setCancelable(false);
final EditText edtQuantity = new EditText(this);
int maxLength = 3;
edtQuantity.setFilters(new InputFilter[]{new InputFilter.LengthFilter(maxLength)});
edtQuantity.setInputType(InputType.TYPE_CLASS_NUMBER);
alert.setView(edtQuantity);
alert.setPositiveButton("Add", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
String temp = edtQuantity.getText().toString();
int quantity = 0;
// when add button clicked add menu to order table in database
if (!temp.equalsIgnoreCase("")) {
quantity = Integer.parseInt(temp);
Toast.makeText(getApplicationContext(), "Success add product to cart", Toast.LENGTH_SHORT).show();
if (dbhelper.isDataExist(Menu_ID)) {
dbhelper.updateData(Menu_ID, quantity, (Menu_price * quantity));
} else {
dbhelper.addData(Menu_ID, Menu_name, quantity, (Menu_price * quantity));
}
checkoutButton.setEnabled(true);
checkoutButton.setBackgroundColor(R.color.ColorPrimaryDark);
checkoutButton.setTextColor(Color.WHITE);
} else {
dialog.cancel();
checkoutButton.setEnabled(false);
}
}
});
alert.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
// when cancel button clicked close dialog
dialog.cancel();
}
});
alert.show();
}
Now the question is
i want to display add to cart button in product list where i place my order directly from product list without opening product detail.
ListActivity is like
public class ActivityMenuList extends AppCompatActivity {
ListView listMenu;
ProgressBar prgLoading;
SwipeRefreshLayout swipeRefreshLayout = null;
EditText edtKeyword;
ImageButton btnSearch;
TextView txtAlert;
// declare static variable to store tax and currency symbol
public static double Tax;
public static String Currency;
private ActivityMenuDetail details;
// declare adapter object to create custom menu list
AdapterMenuList mla;
// create arraylist variables to store data from server
public static ArrayList<Long> Menu_ID = new ArrayList<Long>();
public static ArrayList<String> Menu_name = new ArrayList<String>();
public static ArrayList<Double> Menu_price = new ArrayList<Double>();
public static ArrayList<String> Menu_image = new ArrayList<String>();
public static ArrayList<Double> Discounted_Price = new ArrayList<Double>();
public static ArrayList<String> Discounted_Value = new ArrayList<String>();
public static ArrayList<Double> Our_Price = new ArrayList<Double>();
String MenuAPI;
String fullAPI;
String TaxCurrencyAPI;
int IOConnect = 0;
long Category_ID;
String Category_name;
String Keyword;
// create price format
DecimalFormat formatData = new DecimalFormat("#.##");
DecimalFormat formatData1 = new DecimalFormat("#.##");
DecimalFormat formatData2 = new DecimalFormat("#.##");
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_menu_list);
final Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
final android.support.v7.app.ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setTitle(R.string.title_menu);
}
swipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipeRefreshLayout);
swipeRefreshLayout.setColorSchemeResources(R.color.orange, R.color.green, R.color.blue);
prgLoading = (ProgressBar) findViewById(R.id.prgLoading);
listMenu = (ListView) findViewById(R.id.listMenu);
edtKeyword = (EditText) findViewById(R.id.edtKeyword);
btnSearch = (ImageButton) findViewById(R.id.btnSearch);
txtAlert = (TextView) findViewById(R.id.txtAlert);
// menu API url
MenuAPI = Config.ADMIN_PANEL_URL+"/api/get-menu-data-by-category-id2.php"+"?accesskey="+Config.AccessKey+"&category_id=";
// tax and currency API url
TaxCurrencyAPI = Config.ADMIN_PANEL_URL+"/api/get-tax-and-currency.php"+"?accesskey="+Config.AccessKey;
// get category id and category name that sent from previous page
Intent iGet = getIntent();
Category_ID = iGet.getLongExtra("category_id",0);
Category_name = iGet.getStringExtra("category_name");
MenuAPI += Category_ID;
mla = new AdapterMenuList(ActivityMenuList.this);
// call asynctask class to request tax and currency data from server
new getTaxCurrency().execute();
// event listener to handle search button when clicked
btnSearch.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
// TODO Auto-generated method stub
// get keyword and send it to server
try {
Keyword = URLEncoder.encode(edtKeyword.getText().toString(), "utf-8");
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
MenuAPI += "&keyword=" + Keyword;
IOConnect = 0;
listMenu.invalidateViews();
clearData();
new getDataTask().execute();
}
});
// event listener to handle list when clicked
listMenu.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> arg0, View arg1, int position,
long arg3) {
// TODO Auto-generated method stub
// go to menu detail page
Intent iDetail = new Intent(ActivityMenuList.this, ActivityMenuDetail.class);
iDetail.putExtra("menu_id", Menu_ID.get(position));
startActivity(iDetail);
}
});
// Using to refresh webpage when user swipes the screen
swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
swipeRefreshLayout.setRefreshing(false);
IOConnect = 0;
listMenu.invalidateViews();
clearData();
new getDataTask().execute();
}
}, 3000);
}
});
listMenu.setOnScrollListener(new AbsListView.OnScrollListener() {
#Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
}
#Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
boolean enable = false;
if (listMenu != null && listMenu.getChildCount() > 0) {
boolean firstItemVisible = listMenu.getFirstVisiblePosition() == 0;
boolean topOfFirstItemVisible = listMenu.getChildAt(0).getTop() == 0;
enable = firstItemVisible && topOfFirstItemVisible;
}
swipeRefreshLayout.setEnabled(enable);
}
});
}
#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 i = new Intent(ActivityMenuList.this, ActivityCart.class);
startActivity(i);
return true;
case R.id.refresh:
IOConnect = 0;
listMenu.invalidateViews();
clearData();
new getDataTask().execute();
return true;
case android.R.id.home:
// app icon in action bar clicked; go home
this.finish();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
// asynctask class to handle parsing json in background
public class getTaxCurrency extends AsyncTask<Void, Void, Void>{
// show progressbar first
getTaxCurrency(){
if(!prgLoading.isShown()){
prgLoading.setVisibility(View.VISIBLE);
txtAlert.setVisibility(View.GONE);
}
}
#Override
protected Void doInBackground(Void... arg0) {
// TODO Auto-generated method stub
// parse json data from server in background
parseJSONDataTax();
return null;
}
#Override
protected void onPostExecute(Void result) {
// TODO Auto-generated method stub
// when finish parsing, hide progressbar
prgLoading.setVisibility(View.GONE);
// if internet connection and data available request menu data from server
// otherwise, show alert text
if((Currency != null) && IOConnect == 0){
new getDataTask().execute();
}else{
txtAlert.setVisibility(View.VISIBLE);
}
}
}
// method to parse json data from server
public void parseJSONDataTax(){
try {
// request data from tax and currency API
HttpClient client = new DefaultHttpClient();
HttpConnectionParams.setConnectionTimeout(client.getParams(), 15000);
HttpConnectionParams.setSoTimeout(client.getParams(), 15000);
HttpUriRequest request = new HttpGet(TaxCurrencyAPI);
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 tax and currency variables
JSONObject json = new JSONObject(str);
JSONArray data = json.getJSONArray("data"); // this is the "items: [ ] part
JSONObject object_tax = data.getJSONObject(0);
JSONObject tax = object_tax.getJSONObject("tax_n_currency");
Tax = Double.parseDouble(tax.getString("Value"));
JSONObject object_currency = data.getJSONObject(1);
JSONObject currency = object_currency.getJSONObject("tax_n_currency");
Currency = currency.getString("Value");
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
IOConnect = 1;
// TODO Auto-generated catch block
e.printStackTrace();
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// clear arraylist variables before used
void clearData(){
Menu_ID.clear();
Menu_name.clear();
Menu_price.clear();
Menu_image.clear();
Discounted_Value.clear();
Discounted_Price.clear();
Our_Price.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(View.VISIBLE);
txtAlert.setVisibility(View.GONE);
}
}
#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(View.GONE);
// if data available show data on list
// otherwise, show alert text
if(Menu_ID.size() > 0){
listMenu.setVisibility(View.VISIBLE);
listMenu.setAdapter(mla);
}else{
txtAlert.setVisibility(View.VISIBLE);
}
}
}
// method to parse json data from server
public void parseJSONData(){
clearData();
try {
// request data from menu API
HttpClient client = new DefaultHttpClient();
HttpConnectionParams.setConnectionTimeout(client.getParams(), 15000);
HttpConnectionParams.setSoTimeout(client.getParams(), 15000);
HttpUriRequest request = new HttpGet(MenuAPI);
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"); // this is the "items: [ ] part
for (int i = 0; i < data.length(); i++) {
JSONObject object = data.getJSONObject(i);
JSONObject menu = object.getJSONObject("Menu");
Menu_ID.add(Long.parseLong(menu.getString("Menu_ID")));
Menu_name.add(menu.getString("Menu_name"));
Menu_price.add(Double.valueOf(formatData.format(menu.getDouble("Price"))));
Discounted_Price.add(Double.valueOf(formatData1.format(menu.getDouble("Discounted_Price"))));
Our_Price.add(Double.valueOf(formatData2.format(menu.getDouble("Our_Price"))));
Menu_image.add(menu.getString("Menu_image"));
Discounted_Value.add(menu.getString("Discounted_Value"));
}
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
#Override
protected void onDestroy() {
// TODO Auto-generated method stub
//mla.imageLoader.clearCache();
listMenu.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();
}
ListAdapter code
public class AdapterMenuList extends BaseAdapter {
private Activity activity;
private ActivityMenuDetail details;
public AdapterMenuList(Activity act) {
this.activity = act;
}
public AdapterMenuList(ActivityMenuDetail details) {
this.details = details;
}
public int getCount() {
return ActivityMenuList.Menu_ID.size();
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public View getView(final int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
if(convertView == null){
LayoutInflater inflater = (LayoutInflater) activity
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.lsv_item_menu_list, null);
holder = new ViewHolder();
holder.txtText = (TextView) convertView.findViewById(R.id.txtText);
holder.txtSubText = (TextView) convertView.findViewById(R.id.txtSubText);
holder.imgThumb = (ImageView) convertView.findViewById(R.id.ImageCatList);
holder.discounted_Price = (TextView) convertView.findViewById(R.id.DiscPriceCatList);
holder.discounted_Value = (TextView) convertView.findViewById(R.id.DiscValueCatList);
holder.discounted_Price.setTextColor(Color.GRAY);
holder.discounted_Price.setPaintFlags(holder.discounted_Price.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
holder.addtocart = (TextView) convertView.findViewById(R.id.Listaddtocart);
holder.layout = (LinearLayout) convertView.findViewById(R.id.Listcardview);
holder.our_Price = (TextView) convertView.findViewById(R.id.Our_Price);
convertView.setTag(holder);
}else{
holder = (ViewHolder) convertView.getTag();
}
holder.discounted_Value.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
#Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
#Override
public void afterTextChanged(Editable editable) {
if(editable.toString().equals("0 % off") | editable.toString().equals("00 % off")){
// 1 - You can set empty text
holder.discounted_Value.setText("");
// 2 - Or you can change the color of the text
holder.discounted_Value.setTextColor(Color.TRANSPARENT);
// 3 - Or you can change the visibility of the view
holder.discounted_Value.setVisibility(View.INVISIBLE);
holder.layout.setVisibility(View.GONE);
}else{
//Here you should undo your code
//1 - if you using method one dose not need to do anything here
// for method 2
holder.discounted_Value.setTextColor(Color.BLACK);
// for method 3
holder.discounted_Value.setVisibility(View.VISIBLE);
holder.layout.setVisibility(View.VISIBLE);
}
}
});
holder.txtText.setText(ActivityMenuList.Menu_name.get(position));
holder.txtSubText.setText("\u20B9" + ActivityMenuList.Menu_price.get(position));
holder.discounted_Price.setText("\u20B9" + ActivityMenuList.Discounted_Price.get(position));
holder.discounted_Value.setText(ActivityMenuList.Discounted_Value.get(position)+ " % off");
holder.our_Price.setText("Our Price" + " " + "\u20B9" + ActivityMenuList.Our_Price.get(position));
Picasso.with(activity).load(Config.ADMIN_PANEL_URL+"/"+ActivityMenuList.Menu_image.get(position)).placeholder(R.drawable.loading).into(holder.imgThumb);
return convertView;
}
static class ViewHolder {
TextView txtText, txtSubText, discounted_Price, quantity, discounted_Value, our_Price;
ImageView imgThumb;
TextView addtocart;
LinearLayout layout;
}
}
Any idea how can i put add to cart button in listview item where i place order from list without opening new activity.
thankx.
Yes it is pretty straight forward to do.
Just add the "add to cart" option in every item itself.
So in the listview, show add to cart at the right most side where the user can click to add to the cart directly.
To get the click, in the base adapter in the getView() method, set the click listener on that holder item(add to cart button) and do the stuff in its onClick.
I have a ListView and a list view adapter. The adapter populates the ListView from a List. The list view has a onScrollListener. The problem I have is when on scroll new data are loaded to the view but the scroll bar jumps to the top of the view.
What I want is to keep the scroll position where it was!
Any help?
Thanks
List View class:
private class GetItems extends AsyncTask<Void, Void, Void>
{
#Override
protected void onPreExecute() {
super.onPreExecute();
// Create a progressdialog
mProgressDialog = new ProgressDialog(AppList.this);
// Set progressdialog title
mProgressDialog.setTitle("Loading more");
mProgressDialog.setMessage("loading);
mProgressDialog.setIndeterminate(false);
// Show progressdialog
mProgressDialog.show();
}
#Override
protected Void doInBackground(Void... params)
{
applicationList = new ArrayList();
try
{
GetDataAppList getDataAppList = new GetDataAppList();
JSONArray jsonData = getDataAppList.getJSONData(webfileName, limit, offset);
for (int i = 0; i <= jsonData.length() - 2; i++)
{
JSONObject c = jsonData.getJSONObject(i);
id = c.getString("id");
name = c.getString("name");
logo = c.getString("logo");
developer = c.getString("developer");
rate = c.getInt("rates");
category = c.getInt("category");
fileName = c.getString("filename");
path = c.getString("path");
appSize = c.getDouble("size");
if(category == 1001)
{
String gCat = c.getString("game_category");
applicationList.add(new ApplicationPojo(id,name,logo,developer,appSize,category,fileName,path,gCat));
}
else
{
applicationList.add(new ApplicationPojo(id,name,logo,developer,appSize,category,fileName,path));
}
}
JSONObject sizeObj = jsonData.getJSONObject(jsonData.length() - 1);
size = sizeObj.getInt("size");
}
catch (Exception ex)
{
Log.d("Thread:", ex.toString());
}
return null;
}
#Override
protected void onPostExecute(Void result)
{
// Locate the ListView in listview.xml
listview = (ListView) findViewById(R.id.listView);
// Pass the results into ListViewAdapter.java
adapter = new ListViewAdapter(AppList.this, applicationList,listview);
// Binds the Adapter to the ListView
listview.setAdapter(adapter);
// Close the progressdialog
mProgressDialog.dismiss();
// Create an OnScrollListener
listview.setOnScrollListener(new OnScrollListener() {
#Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
int threshold = 1;
int count = listview.getCount();
if (scrollState == SCROLL_STATE_IDLE) {
if (listview.getLastVisiblePosition() >= count - threshold) {
if (size >= offset)
{
new LoadMoreDataTask().execute();
offset = offset + 15;
}
else
{
Toast.makeText(getApplicationContext(), "ختم لست!", Toast.LENGTH_LONG).show();
}
}
}
}
#Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
// TODO Auto-generated method stub
}
});
RatingBar bar = (RatingBar) findViewById(R.id.ratingBarShow);
}
}
private class LoadMoreDataTask extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
mProgressDialog = new ProgressDialog(AppList.this);
mProgressDialog.setTitle("Loading more");
mProgressDialog.setMessage("loading);
mProgressDialog.setIndeterminate(false);
mProgressDialog.show();
}
#Override
protected Void doInBackground(Void... params)
{
try
{
GetDataAppList getDataAppList = new GetDataAppList();
JSONArray jsonData = getDataAppList.getJSONData(webfileName, limit, offset);
for (int i = 0; i <= jsonData.length(); i++) {
JSONObject c = jsonData.getJSONObject(i);
id = c.getString("id");
name = c.getString("name");
logo = c.getString("logo");
developer = c.getString("developer");
rate = c.getInt("rates");
category = c.getInt("category");
fileName = c.getString("filename");
path = c.getString("path");
appSize = c.getDouble("size");
if(category == 1001)
{
String gCat = c.getString("game_category");
applicationList.add(new ApplicationPojo(id,name,logo,developer,appSize,category,fileName,path,gCat));
}
else
{
applicationList.add(new ApplicationPojo(id,name,logo,developer,appSize,category,fileName,path));
}
}
}
catch (Exception ex)
{
}
return null;
}
#Override
protected void onPostExecute(Void result)
{
int position = listview.getLastVisiblePosition();
adapter = new ListViewAdapter(AppList.this, applicationList,listview);
listview.setAdapter(adapter);
listview.setSelectionFromTop(position, 0);
mProgressDialog.dismiss();
}
}
The Adpater class:
public ListViewAdapter(Activity activity, ArrayList<ApplicationPojo> applicationList, ListView listView)
{
this.activity = activity;
this.applicationList = applicationList;
this.inflater = LayoutInflater.from(activity);
downloader = new ApkFileDownloader(activity);
this.listView = listView;
}
#Override
public int getCount() {
return applicationList.size();
}
#Override
public ApplicationPojo getItem(int position) {
return applicationList.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
public View getView(final int position, View view, ViewGroup parent)
{
if (view == null)
{
holder = new ViewHolder();
view = inflater.inflate(R.layout.singleapp, null);
holder.openInstalledAppBtn = (ImageView) view.findViewById(R.id.openInstalledApp);
holder.downloadBtn = (ImageView) view.findViewById(R.id.updateApp);
holder.progressBar = (ProgressBar)view.findViewById(R.id.updateProgress);
holder.cancelBtn = (ImageView) view.findViewById(R.id.cancel);
holder.appName = (TextView) view.findViewById(R.id.appName);
holder.developer = (TextView) view.findViewById(R.id.developer);
holder.size = (TextView) view.findViewById(R.id.size);
holder.appCat = (TextView) view.findViewById((R.id.appCat));
holder.installBtn = (ImageView) view.findViewById(R.id.install);
holder.catlogo = (ImageView) view.findViewById(R.id.catlogo);
view.setTag(holder);
}
else
{
holder = (ViewHolder) view.getTag();
}
try
{
final View finalView = view;
holder.logo = (ImageView) finalView.findViewById(R.id.appLogo);
logoName = applicationList.get(position).getLogo();
Picasso.with(activity)
.load(IPClass.SERVERIP + logoName)
.into(holder.logo);
// holder.logo.setOnClickListener(new View.OnClickListener() {
// #Override
// public void onClick(View arg0) {
//
// }
// });
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
String appid = applicationList.get(position).getId();
int category = applicationList.get(position).getCategory();
Intent rec1Intent = new Intent(activity, AppView.class);
activity.startActivity(rec1Intent);
AppView appView = new AppView();
appView.setParameters(appid, category);
AppList.adapter.notifyDataSetChanged();
}
});
final String id = applicationList.get(position).getId();
final String path = applicationList.get(position).getPath();
final String fileName = applicationList.get(position).getFileName();
final String name = applicationList.get(position).getName();
final String developer = applicationList.get(position).getDeveloper();
final double size = applicationList.get(position).getSize();
final String logo = applicationList.get(position).getLogo();
final int category = applicationList.get(position).getCategory();
final String appName = applicationList.get(position).getFileName();
String checkAppInstalled = appName.substring(0,appName.length() - 4);
//------------CHECK IF APPLICATION IS INSTALLED ----------------------------------------
if(appInstalled(checkAppInstalled))
{
holder.downloadBtn.setVisibility(View.GONE);
holder.cancelBtn.setVisibility(View.GONE);
holder.progressBar.setVisibility(View.GONE);
holder.installBtn.setVisibility(View.GONE);
holder.openInstalledAppBtn.setVisibility(View.VISIBLE);
holder.openInstalledAppBtn.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v) {
String fileName = (applicationList.get(position).getFileName());
String appToOpen = fileName.substring(0,fileName.length() - 4);
Context ctx = activity.getApplicationContext();
Intent mIntent = ctx.getPackageManager().getLaunchIntentForPackage(appToOpen);
String mainActivity = mIntent.getComponent().getClassName();
Intent intent = new Intent("android.intent.category.LAUNCHER");
intent.setClassName(appToOpen, mainActivity);
activity.startActivity(intent);
}
});
}
//------------- IF APPLICATION IS NOT ALREADY INSTALLED --------------------------------
else
{
//------------------------ CHECK IF APK EXISTS -------------------------------------
String filePath = Environment.getExternalStorageDirectory().toString();
File file = new File(filePath + "/appsaraai/" + fileName);
if(file.exists())
{
holder.downloadBtn.setVisibility(View.GONE);
holder.cancelBtn.setVisibility(View.GONE);
holder.openInstalledAppBtn.setVisibility(View.GONE);
holder.progressBar.setVisibility(View.GONE);
holder.installBtn.setVisibility(View.VISIBLE);
holder.installBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(new File(Environment.getExternalStorageDirectory() + "/appsaraai/" + fileName)), "application/vnd.android.package-archive");
activity.startActivity(intent);
for (int i = 0; i < DownloadLists.list.size(); i++) {
if (DownloadLists.list.get(i).getName().equals(name)) {
DownloadLists.list.remove(i);
}
}
}
});
AppList.adapter.notifyDataSetChanged();
}
//------------------ IF APK DOES NOT EXIST -----------------------------------------
else
{
//-----CHECK IF DOWNLOAD IS IN PROGRESS ----------------------------------------
if (ApkFileDownloader.applicationList.containsKey(name))
{
holder.downloadBtn.setVisibility(View.GONE);
holder.installBtn.setVisibility(View.GONE);
holder.openInstalledAppBtn.setVisibility(View.GONE);
new ApkFileDownloader(activity).getDownloadStatus(holder.progressBar, name, holder.installBtn, holder.cancelBtn);
holder.progressBar.setVisibility(View.VISIBLE);
holder.cancelBtn.setVisibility(View.VISIBLE);
holder.cancelBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
downloader.cancelDownload(name);
holder.cancelBtn.setVisibility(View.GONE);
holder.downloadBtn.setVisibility(View.VISIBLE);
DownloadLists dlist = new DownloadLists(activity);
dlist.deleteData(name);
try {
AppList.adapter.notifyDataSetChanged();
} catch (Exception ex) {
System.out.println(ex);
}
try
{
SearchResult.adapter.notifyDataSetChanged();
}
catch (Exception ex)
{
System.out.println(ex);
}
}
});
}
//-------------- IF DOWNLOAD IS NOT IN PROGRESS START NEW DOWNLOAD -------------
else
{
holder.progressBar.setVisibility(View.GONE);
holder.cancelBtn.setVisibility(View.GONE);
holder.installBtn.setVisibility(View.GONE);
holder.openInstalledAppBtn.setVisibility(View.GONE);
holder.downloadBtn.setVisibility(view.VISIBLE);
holder.downloadBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
holder.downloadBtn.setVisibility(View.GONE);
holder.cancelBtn.setVisibility(View.VISIBLE);
holder.cancelBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
downloader.cancelDownload(name);
holder.cancelBtn.setVisibility(View.GONE);
holder.downloadBtn.setVisibility(View.VISIBLE);
try {
AppList.adapter.notifyDataSetChanged();
} catch (Exception ex) {
System.out.println(ex);
}
try {
SearchResult.adapter.notifyDataSetChanged();
} catch (Exception ex) {
System.out.println(ex);
}
}
});
new Thread(new Runnable() {
#Override
public void run() {
try {
Bitmap logoImg = Picasso.with(activity).load(IPClass.SERVERIP + logo).get();
DownloadLists.list.add(new ApplicationPojo(id, name, developer, size, logoImg, holder.progressBar));
DownloadLists dlist = new DownloadLists(activity);
dlist.insertData(id, name, developer, size, fileName, logoImg);
UpdateServerDownload d = new UpdateServerDownload();
d.updateDownloadNo(id, category);
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
new ApkFileDownloader(activity).setParameters(path, fileName, name);
try {
AppList.adapter.notifyDataSetChanged();
} catch (Exception ex) {
System.out.println(ex);
}
try {
SearchResult.adapter.notifyDataSetChanged();
} catch (Exception ex) {
System.out.println(ex);
}
}
});
}
}
}
holder.appName.setText(applicationList.get(position).getName());
holder.developer.setText(applicationList.get(position).getDeveloper());
String sizeText = " میگابایت ";
String appSize =String.valueOf(applicationList.get(position).getSize()) + sizeText;
holder.size.setText(appSize);
if(category == 1001)
{
String cat = applicationList.get(position).getgCat();
holder.appCat.setText(" " + returnGameCat(cat));
holder.catlogo.setImageResource(R.drawable.gamecatlogo);
}
}
catch (Exception ex)
{
Log.d("Adapter Exception", ex.toString());
}
return view;
}
//--------------- A METHOD TO CHECK IF APPLICATION IS ALREADY INSTALLED ------------------------
public boolean appInstalled(String checkApp)
{
pm = activity.getPackageManager();
try
{
pm.getPackageInfo(checkApp, PackageManager.GET_ACTIVITIES);
isAppInstalled = true;
}
catch (PackageManager.NameNotFoundException e)
{
isAppInstalled = false;
}
return isAppInstalled;
}
You are doing wrong in your GetItems and LoadMoreDataTask AsyncTask. you are setting new adapter each time when you scroll down so when new data are loaded to the view the scroll bar jumps to the top of the view.
You need to call
adapter = new ListViewAdapter(AppList.this, applicationList,listview);
listview.setAdapter(adapter);
only first time then you have to only call
adapter.notifyDataSetChanged()
to update your ListView no need to set adapter each time when making new request and also you have to set OnScrollListener to ListView only one time currently new OnScrollListener is set each time when making new request.
You need to setAdapter first time when adapter is null or you are fetching data first time after it just call notifyDataSetChanged()
Save state of listview before updating and then restore:
// save index and top position
int index = mListView.getFirstVisiblePosition();
View v = mListView.getChildAt(0);
int top = (v == null) ? 0 : v.getTop();
// notify dataset changed or re-assign adapter here
// restore the position of listview
mListView.setSelectionFromTop(index, top);
The most Optimal Solution will be
// Save the ListView state (= includes scroll position) as a Parceble
Parcelable state = listView.onSaveInstanceState();
// e.g. set new items
listView.setAdapter(adapter);
// Restore previous state (including selected item index and scroll position)
listView.onRestoreInstanceState(state);
Reference : Retain Scroll Position Android ListView
int globalPosition ;
..............
buttonAllData.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
new UploadBulkData(globalPosition).execute();
}
});
........
class UploadBulkData extends AsyncTask<String, String, String> {
private ProgressDialog pDialog;
int dataPosition;
public UploadBulkData(int position){
this.dataPosition = position;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(UploadActivity.this);
pDialog.setMessage("Uploading...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(true);
pDialog.show();
}
#Override
protected String doInBackground(String... args) {
.......
String url = "http://web/uploadBulk.php";
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("UserData", st));
String resultServer = getHttpPost(url,params);
Log.d("Entire string::", " " + resultServer);
/*** Default Value ***/
strStatusID = "0";
strError = "";
JSONObject jsonObject;
try {
jsonObject = new JSONObject(resultServer);
strStatusID = jsonObject.getString("StatusID");
strError = jsonObject.getString("Message");
} catch (JSONException e) {
e.printStackTrace();
}
}
return null;
}
protected void onPostExecute(String file_url) {
pDialog.dismiss();
fileNameDB=ImageList.get(globalPosition).toString().substring
(strPath.lastIndexOf('/')+1, strPath.length());
if(strStatusID.equals("1"))
{
Toast.makeText(UploadActivity.this, "Data Uploaded Successfully", Toast.LENGTH_SHORT).show();
long saveImge = myDbbv.InsertData(fileNameDB);
Log.d("fileNameDB:UP", String.valueOf(saveImge));
}
else
{
Toast.makeText(UploadActivity.this, "Unable to upload Data", Toast.LENGTH_SHORT).show();
}
if (file_url != null){
Toast.makeText(UploadActivity.this, file_url, Toast.LENGTH_LONG).show();
}
}
}
And in getView i am using something like this:
public View getView(final int position, View convertView, ViewGroup parent) {
holder.dataImageView.setImageResource(R.drawable.bullet_button);
try {
// check data exist or not
boolean strDataExistU = myDbbv.Exists(fileNameDB);
if(strDataExistU)
{
holder.dataImageView.setImageResource(R.drawable.online);
}
else
{
boolean strDataExist = myDb.Exists(fileNameDB);
if(strDataExist)
{
holder.dataImageView.setImageResource(R.drawable.local);
}
else
{
holder.dataImageView.setImageResource(R.drawable.default);
}
}
} catch (Exception e) {
}
}
As you can see in getView(...) method, I am using three different kind of drawables (namely:- online, local, default)
Where online shows data has been uploaded to online server, local shows this has been added to local database and default..(neither uploaded to server nor stored to local database)
Problem:
Whenever I am doing bulk upload, getting online drawable only for the last row item in a list, whereas I have uploaded whole list item data to server
I just want to show online drawable for all the list items, those I have uploaded to server, else my code works just fine...
Almost complete code:
public class UploadActivity extends Activity {
int globalPosition ;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_upload);
ImageButton buttonAllData = (ImageButton) findViewById(R.id.btnMenus);
buttonAllData.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
new UploadBulkData(globalPosition).execute();
}
});
/*** Get Images from SDCard ***/
ImageList = getSD();
// ListView and imageAdapter
lstView = (ListView) findViewById(R.id.listView1);
lstView.setAdapter(new ImageAdapter(this));
totalItems = ""+ lstView.getAdapter().getCount();
}
public static List <String> getSD()
{
List <String> it = new ArrayList <String>();
String string = "/mnt/sdcard/Pictures/Joseph/";
f = new File (string+ CameraLauncherActivity.folder+ "/");
files = f.listFiles ();
/***
* to show last taken image on top using lastModified
* to sort data
* to refresh data after (remove or update)
*/
Arrays.sort(files, new Comparator<Object>()
{
public int compare(Object o1, Object o2) {
if (((File)o1).lastModified() > ((File)o2).lastModified()) {
return -1;
} else if (((File)o1).lastModified() < ((File)o2).lastModified()) {
return +1;
} else {
return 0;
}
}
});
// <<<<<<<<< END >>>>>>>>>>>
for (int i = 0; i < files.length; i++)
{
file = files[i];
Log.d("Count",file.getPath());
it.add (file.getPath());
}
return it;
}
static class ViewHolder {
public ViewHolder(View convertView) {
// TODO Auto-generated constructor stub
}
TextView imageNameTextView;
ImageView sdCardImageView, statusImageView, dataImageView;
ProgressBar uploadProgressBar;
ImageButton uploadImageButton, dataImageButton;
boolean isUploading = false;
}
public class ImageAdapter extends BaseAdapter
{
public ImageAdapter(Context c)
{
}
public int getCount() {
// TODO Auto-generated method stub
return ImageList.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(final int position, View convertView, ViewGroup parent) {
// Avoid unneccessary calls to findViewById() on each row, which is expensive!
holder = null;
// If this item is to be synced
if(flags.get(position)) {
startUpload(position);
// Mark as synced
flags.put(position, false);
}
/*
* If convertView is not null, we can reuse it directly, no inflation required!
* We only inflate a new View when the convertView is null.
*/
if (convertView == null) {
convertView = getLayoutInflater().inflate(R.layout.list_upload, null);
holder = new ViewHolder(convertView);
// Create a ViewHolder and store references to the children views
holder.imageNameTextView = (TextView) convertView.findViewById(R.id.ColImgName);
holder.sdCardImageView = (ImageView) convertView.findViewById(R.id.ColImgPath);
holder.statusImageView = (ImageView) convertView.findViewById(R.id.ColStatus);
holder.uploadProgressBar = (ProgressBar) convertView.findViewById(R.id.progressBar);
holder.uploadImageButton = (ImageButton) convertView.findViewById(R.id.btnUpload);
holder.dataImageButton = (ImageButton) convertView.findViewById(R.id.btnData);
holder.dataImageView = (ImageView) convertView.findViewById(R.id.dataExist);
// The tag can be any Object, this just happens to be the ViewHolder
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
strPath = ImageList.get(position).toString();
// Get File Name
fileName = strPath.substring( strPath.lastIndexOf('_')+1, strPath.length() );
file = new File(strPath);
#SuppressWarnings("unused")
long length = file.length();
holder.imageNameTextView.setText(fileName);
fileName=ImageList.get(position).toString().substring
(strPath.lastIndexOf('_')+1, strPath.length());
fileNameDB=ImageList.get(position).toString().substring
(strPath.lastIndexOf('/')+1, strPath.length());
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 8;
Bitmap bm = BitmapFactory.decodeFile(strPath,options);
holder.sdCardImageView.setImageBitmap(bm);
if(holder.isUploading) {
holder.uploadProgressBar.setVisibility(View.VISIBLE);
} else {
holder.uploadProgressBar.setVisibility(View.GONE);
}
holder.dataImageView.setImageResource(R.drawable.bullet_button);
try {
// check data exist or not
boolean strDataExistU = myDbbv.Exists(fileNameDB);
if(strDataExistU)
{
holder.dataImageView.setImageResource(R.drawable.online);
}
else
{
// check data exist or not
boolean strDataExist = myDb.Exists(fileNameDB);
if(strDataExist)
{
holder.dataImageView.setImageResource(R.drawable.database);
}
else
{
holder.dataImageView.setImageResource(R.drawable.default);
}
}
} catch (Exception e) {
// TODO: handle exception
}
fileName = ImageList.get(position).toString().substring
(strPath.lastIndexOf('/')+1, strPath.length());
try {
boolean strExist = myDbb.Exists(fileName);
if(strExist)
{
holder.statusImageView.setImageResource(R.drawable.onl);
}
else
{
holder.statusImageView.setImageResource(R.drawable.bullet_button);
}
} catch (Exception e) {
// TODO: handle exception
}
// btnData
holder.dataImageButton.setOnClickListener(new View.OnClickListener() {
#SuppressWarnings("deprecation")
public void onClick(View v) {
// Print
globalPosition = position;
fileName=ImageList.get(position).toString().substring
(strPath.lastIndexOf('_')+1, strPath.length());
fileNameDB=ImageList.get(position).toString().substring
(strPath.lastIndexOf('/')+1, strPath.length());
showDialog(DIALOG_LOGIN);
}
});
return convertView;
}
}
class UploadData extends AsyncTask<String, String, String> {
private ProgressDialog pDialog;
/**
* Before starting background thread Show Progress Dialog
* */
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(UploadActivity.this);
pDialog.setMessage("Uploading...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(true);
pDialog.show();
}
#Override
protected String doInBackground(String... args) {
String url = "http://web/uploadData.php";
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("sImageName", fileNameDB));
Log.d("sImageName::", fileNameDB);
String resultServer = getHttpPost(url,params);
Log.d("Entire string::", " " + resultServer);
/*** Default Value ***/
strStatusID = "0";
strError = "";
JSONObject c;
try {
c = new JSONObject(resultServer);
strStatusID = c.getString("StatusID");
strError = c.getString("Error");
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
/**
* After completing background task Dismiss the progress dialog
* **/
protected void onPostExecute(String file_url) {
// dismiss the dialog once product deleted
pDialog.dismiss();
try {
fileName=ImageList.get(globalPosition).toString().substring
(strPath.lastIndexOf('_')+1, strPath.length());
fileNameDB=ImageList.get(globalPosition).toString().substring
(strPath.lastIndexOf('/')+1, strPath.length());
// prepare save data
if(strStatusID.equals("0"))
{
Toast.makeText(getApplicationContext(), "Unable to upload Data",
Toast.LENGTH_LONG).show();
}
else if (strStatusID.equals("1"))
{
Toast.makeText(getApplicationContext(), "Data Uploaded Successfully!",
Toast.LENGTH_SHORT).show();
// Save Data
long saveImge = myDbbv.InsertData(fileNameDB);
Log.d("fileNameDB:UP", String.valueOf(saveImge));
} else {
Toast.makeText(getApplicationContext(), "Unable to upload Data",
Toast.LENGTH_LONG).show();
}
} catch (Exception e) {
// TODO: handle exception
}
if (file_url != null){
Toast.makeText(UploadActivity.this, file_url, Toast.LENGTH_LONG).show();
}
}
}
});
cancelButton.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
alertDialog.dismiss();
}
});
closeButton.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
alertDialog.dismiss();
}
});
}
}
class UploadBulkData extends AsyncTask<String, String, String> {
private ProgressDialog pDialog;
int dataPosition;
//constructor to pass position of row, on which button was clicked to class
public UploadBulkData(int position){
this.dataPosition = position;
}
/**
* Before starting background thread Show Progress Dialog
* */
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(UploadActivity.this);
pDialog.setMessage("Uploading...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(true);
pDialog.show();
}
#Override
protected String doInBackground(String... args) {
String url = "http://web/uploadBulk.php";
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("EventData", st));
String resultServer = getHttpPost(url,params);
Log.d("Entire string::", " " + resultServer);
/*** Default Value ***/
strStatusID = "0";
strError = "";
JSONObject jsonObject;
try {
jsonObject = new JSONObject(resultServer);
strStatusID = jsonObject.getString("StatusID");
strError = jsonObject.getString("Message");
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return null;
}
/**
* After completing background task Dismiss the progress dialog
* **/
protected void onPostExecute(String file_url) {
// dismiss the dialog once product deleted
pDialog.dismiss();
// Prepare Save Data
if(strStatusID.equals("1"))
{
Toast.makeText(UploadActivity.this, "Data Uploaded Successfully", Toast.LENGTH_SHORT).show();
fileNameDB=ImageList.get(dataPosition).toString().substring
(strPath.lastIndexOf('/')+1, strPath.length());
// Save Data
long saveImge = myDbbv.InsertData(fileNameDB);
Log.d("fileNameDB:UP", String.valueOf(saveImge));
}
else
{
Toast.makeText(UploadActivity.this, "Unable to upload Data", Toast.LENGTH_SHORT).show();
}
if (file_url != null){
Toast.makeText(UploadActivity.this, file_url, Toast.LENGTH_LONG).show();
}
}
}
Issue is in holder.dataImageButton.setOnClickListener method block, position value you are assigning to globalPosition (globalPosition = position;) is the one passed to getView method (getView is called every time view is recycled). So you should set position to holder.dataImageButton tag and retrieve from it inside your setOnClickListener method block.
So set the position in holder.dataImageButton tag
holder.dataImageButton.setTag(position);
after your code line
holder.dataImageView.setImageResource(R.drawable.bullet_button);
and modify your setOnClickListener method as
holder.dataImageButton.setOnClickListener(new View.OnClickListener() {
#SuppressWarnings("deprecation")
public void onClick(View v) {
// Print
globalPosition = (Integer)v.getTag(); //modified
fileName=ImageList.get(position).toString().substring
(strPath.lastIndexOf('_')+1, strPath.length());
fileNameDB=ImageList.get(position).toString().substring
(strPath.lastIndexOf('/')+1, strPath.length());
showDialog(DIALOG_LOGIN);
}
});
It appears that in both UploadData and UploadBulkData the exact same code is used for updating the uploaded database: myDbbv.InsertData(fileNameDB). This would have the effect of only marking the last file of UploadBulkData as being uploaded, which is consistent with the problematic behavior you are seeing.
Try updating myDbbv for each file being uploaded in UploadData and see if it helps.
There could be multiple customizable ways to achieve this. One of them is already answered. Correct me if I'm wrong about your requirement, you need to be notified when the list reached its last item. Afterwards, you're going to perform an operation with the last item index.
[UPDATE]
For this solution: You have to migrate to Recycler View as it's more flexible, fast and optimised for bulk data.
int findFirstVisibleItemPosition();
int findFirstCompletelyVisibleItemPosition();
int findLastVisibleItemPosition(); // This function could be the one you're looking for.
int findLastCompletelyVisibleItemPosition();
Usage:
// In Java
GridLayoutManager layoutManager = ((GridLayoutManager)mRecyclerView.getLayoutManager());
int firstVisiblePosition = layoutManager.findFirstVisibleItemPosition();
Reference: https://stackoverflow.com/a/25053500/16176653
Sorry for my bad english.I am new to android and i parsed json data into listview,now i want to put on him a search functionality,but i have a problem,when i entered a words in edittext,then in the listview my items are duplicated,and items has been increases,look my code and screen shots.Thanks in advance and any help will be much appreciated.
My Artist Activity:
public class Artists extends Activity {
// Connection detector
ConnectionDetector cd;
// Alert dialog manager
AlertDialogManager alert = new AlertDialogManager();
// Progress Dialog
private ProgressDialog pDialog;
// Creating JSON Parser object
JSONParser jsonParser = new JSONParser();
// This is not using now if you want you can remove its all references :)
ArrayList<HashMap<String, String>> albumsList;
ArrayList<AdapterDTOArtist> mAdapterDTOs = null;
private LazyAdapterArtist mLazyAdatper = null;
private ArrayList<String> array_sort = new ArrayList<String>();
int textlength = 0;
// albums JSONArray
JSONArray albums = null;
LinearLayout ll_artists_chart;
LinearLayout ll_artists_newrelease;
private EditText etSearch;
private static String URL_ALBUMS = "http://triplevmusic.com/dev/webservice/index.php?op=fetch_artists.json";
// JSON Node names
private static final String TAG_CONTACTS = "data";
private static final String TAG_ID = "id";
private static final String TAG_NAME = "name";
private ListView lv = null;
EditText et_artists_searchWord;
// contacts JSONArray
JSONArray contacts = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.artists);
lv = (ListView) findViewById(R.id.artist_main_list_id);
cd = new ConnectionDetector(getApplicationContext());
// Check for internet connection
if (!cd.isConnectingToInternet()) {
// Internet Connection is not present
alert.showAlertDialog(Artists.this,
"Internet Connection Error",
"Please connect to working Internet connection", false);
// stop executing code by return
return;
}
// Hashmap for ListView
albumsList = new ArrayList<HashMap<String, String>>();
mAdapterDTOs = new ArrayList<AdapterDTOArtist>();
// Loading Albums JSON in Background Thread
new LoadAlbums().execute();
// get listview
/**
* Listview item click listener TrackListActivity will be lauched by
* passing album id
* */
lv.setOnItemClickListener(new android.widget.AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View view, int arg2,
long arg3) {
// on selecting a single album
}
});
ll_artists_chart = (LinearLayout) findViewById(R.id.ll_artists_chart);
ll_artists_newrelease = (LinearLayout) findViewById(R.id.ll_artists_newrelease);
et_artists_searchWord = (EditText) findViewById(R.id.et_artists_searchWord);
et_artists_searchWord.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
// TODO Auto-generated method stub
// ((Filterable) Artists.this.mAdapterDTOs).getFilter().filter(s);
List<AdapterDTOArtist> list = filter(s.toString(),mAdapterDTOs, true);
mAdapterDTOs.addAll(list);
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
// TODO Auto-generated method stub
}
#Override
public void afterTextChanged(Editable s) {
// TODO Auto-generated method stub
}
});
ll_artists_chart.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent intent = new Intent(getBaseContext(), ChartActivity.class);
startActivity(intent);
// finish();
}
});
ll_artists_newrelease.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent intent = new Intent(getBaseContext(), NewReleases.class);
startActivity(intent);
//finish();
}
});
}
/**
* Background Async Task to Load all Albums by making http request
* */
class LoadAlbums extends AsyncTask<String, String, String> {
/**
* Before starting background thread Show Progress Dialog
* */
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(Artists.this);
pDialog.setMessage("Listing Artists ...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(false);
pDialog.show();
}
/**
* getting Albums JSON
* */
protected String doInBackground(String... args) {
// Building Parameters
//List<NameValuePair> params = new ArrayList<NameValuePair>();
ArrayList<HashMap<String, String>> contactList = new ArrayList<HashMap<String, String>>();
// Creating JSON Parser instance
JSONParser jParser = new JSONParser();
JSONObject json = jParser.getJSONFromUrl(URL_ALBUMS);
// getting JSON string from URL
//String json = jsonParser.makeHttpRequest(URL_ALBUMS, "GET", params);
// Check your log cat for JSON reponse
Log.i("Albums JSON: ", "> " + json);
try {
//albums = new JSONArray(json);
albums = json.getJSONArray(TAG_CONTACTS);
if (albums != null) {
// looping through All albums
for (int i = 0; i < albums.length(); i++) {
JSONObject c = albums.getJSONObject(i);
// Storing each json item values in variable
String id = c.getString(TAG_ID);
String name = c.getString(TAG_NAME);
/*String EateryThmbnailUrl = c
.getString(TAG_THMBNAIL_URL);*/
// ~\/Uploads\/EateryImages\/\/7\/41283f1f-8e6f-42d4-b3c1-01f990efb428.gif
/*EateryThmbnailUrl = HOST_URL
+ EateryThmbnailUrl.replace("~", "");*/
AdapterDTOArtist adapterDTO = new AdapterDTOArtist();
adapterDTO.setmTag_Id(id);
adapterDTO.setmTag_Name(name);
// adapterDTO.setmImage_URL(EateryThmbnailUrl);
mAdapterDTOs.add(adapterDTO);
// creating new HashMap
HashMap<String, String> map = new HashMap<String, String>();
HashMap<String, Integer> map1 = new HashMap<String, Integer>();
// adding each child node to HashMap key => value
map.put(TAG_ID, id);
map.put(TAG_NAME, name);
// adding HashList to ArrayList
albumsList.add(map);
}
} else {
Log.d("Albums: ", "null");
}
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
/**
* After completing background task Dismiss the progress dialog
* **/
protected void onPostExecute(String file_url) {
// dismiss the dialog after getting all albums
pDialog.dismiss();
// updating UI from Background Thread
runOnUiThread(new Runnable() {
public void run() {
/**
* Updating parsed JSON data into ListView
* */
// updating listview
mLazyAdatper = new LazyAdapterArtist(Artists.this,
mAdapterDTOs);
lv.setAdapter(mLazyAdatper);
// mLazyAdatper.setDataSet(mAdapterDTOs);
}
});
}
}
public static List<AdapterDTOArtist> filter(String string,
Iterable<AdapterDTOArtist> iterable, boolean byName) {
if (iterable == null)
return new LinkedList<AdapterDTOArtist>();
else {
List<AdapterDTOArtist> collected = new LinkedList<AdapterDTOArtist>();
Iterator<AdapterDTOArtist> iterator = iterable.iterator();
if (iterator == null)
return collected;
while (iterator.hasNext()) {
AdapterDTOArtist item = iterator.next();
collected.add(item);
}
return collected;
}
}
}
My AdapterDTOArtist class :
public class AdapterDTOArtist {
private String mTag_Id;
private String mTag_Name;
public String getmTag_Name() {
return mTag_Name;
}
public void setmTag_Name(String mTag_Name) {
this.mTag_Name = mTag_Name;
}
public String getmTag_Id() {
return mTag_Id;
}
public void setmTag_Id(String mTag_Id) {
this.mTag_Id = mTag_Id;
}
}
My LazyAdapterArtist class:
public class LazyAdapterArtist extends BaseAdapter {
private Context mContext = null;
private ArrayList<AdapterDTOArtist> mAdapterDTOs = null;
public LazyAdapterArtist(Context context,
ArrayList<AdapterDTOArtist> mAdapterDTOs2) {
// TODO Auto-generated constructor stub
this.mContext = context;
this.mAdapterDTOs = mAdapterDTOs2;
}
public void setDataSet(ArrayList<AdapterDTOArtist> adapterDTOs) {
this.mAdapterDTOs = adapterDTOs;
notifyDataSetChanged();
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return mAdapterDTOs.size();
}
#Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return null;
}
#Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
View row = convertView;
ViewHolder mHolder = new ViewHolder();
if (row == null) {
// Cell is inflating for first time
row = LayoutInflater.from(mContext)
.inflate(com.whizpool.triplevmusic.R.layout.row_artists,
null, false);
mHolder.mNameTxt = (TextView) row
.findViewById(com.whizpool.triplevmusic.R.id.tv_row_artists);
row.setTag(mHolder);
} else {
// recycling of cells
mHolder = (ViewHolder) row.getTag();
}
mHolder.mNameTxt.setText(mAdapterDTOs.get(position).getmTag_Name());
return row;
}
static class ViewHolder {
TextView mNameTxt = null;
}
}
when parsed json data into listview my app look like this:
when enter word in edittext field then my app look like this:
I just want,when i entered the word for example i enter "D" then in a listview only those words were display which have starting word is "D".Thanks Alot and again sorry for my english.
The problem is that when you filter the data you add again to mAdapterDTOs list the results you need to clear the list before adding the results. To avoid losing your data you have to keep them in a separate list and when user times nothing show them.
Step 1: Use a field for keeping a backup of your data (just as mAdapterDTOs):
ArrayList<AdapterDTOArtist> mAdapterDTOs = null;
ArrayList<AdapterDTOArtist> mAdapterDTOsBackup= null;
Step 2: initialize that field:
mAdapterDTOs = new ArrayList<AdapterDTOArtist>();
mAdapterDTOsBackup = new ArrayList<AdapterDTOArtist>();
Step 3: Fill in all your data to the backup set just after parsing:
/**
* getting Albums JSON
* */
protected String doInBackground(String... args) {
// HERE all your code as it is!!!
// Just before return add a set keeping the backup of your data...
// initialize the set just as mAdapterDTOs
mAdapterDTOsBackup.addAll(mAdapterDTOs);
return null;
}
Step 4: When searching filter data from backup set and then add them on the mAdapterDTOs do not forget to clear it before.
et_artists_searchWord.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
// TODO Auto-generated method stub
// ((Filterable) Artists.this.mAdapterDTOs).getFilter().filter(s);
List<AdapterDTOArtist> list = filter(s.toString(),mAdapterDTOsBackup, true);
mAdapterDTOs.clear(); // <--- clear the list before add
mAdapterDTOs.addAll(list); // <--- here is the double add if you do not clear before
mLazyAdatper.setDataSet(mAdapterDTOs);// update the adapter data (edit 2)
}
Edit: split answer in steps in order to be more clear the process also added at least one of your line to show where to add each code snippet.
I never got this working in a straightforward manner. Sorry if I'm being a little vague. I'll try to elaborate on what I'm trying to do. I am trying to build a listview that grabs its data from a webservice. Once I initialize a listview, I want to keep polling the webserver periodically and update the contents of the listview. For this I am doing something like this:
public class SampleAutoUpdateList extends Activity {
//Autoupdate handler
private Handler handler = new Handler();
private Runnable updater = new Runnable() {
public void run() {
/*
* Update the list
*/
try {
Log.i("UPDATE", "Handler called");
searchAdapter = getFeed(URL);
searchAdapter.notifyDataSetChanged();
handler.postDelayed(this, Configuration.REFRESH_INTERVAL);
} catch(Exception e) {
Log.e("UPDATE ERROR", e.getMessage());
}
}
};
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.linearmode);
this.context = this;
searchAdapter = getFeed(URL);
LinearLayout l2 = (LinearLayout) findViewById(R.id.secondaryLayout);
ListView list = new ListView(context);
l2.addView(list);
// display UI
UpdateDisplay(list);
updater.run();
}
private SearchAdapter getFeed(String URL) {
try
{
SearchHandler handler = new SearchHandler();
URL url = new URL(URL);
String data = convertStreamToString(url.openStream());
data = data.substring(data.indexOf('['), data.length()-1);
handler.parseJSON(data);
return handler.getFeed();
}
catch (Exception ee)
{
// if we have a problem, simply return null
Log.e("getFeed", ee.getMessage());
return null;
}
}
private void UpdateDisplay(View searchView) {
// TODO Auto-generated method stub
// TODO Auto-generated method stub
searchList = (ListView) searchView;
myProgressDialog = ProgressDialog.show(this,
"Please wait...", "Loading search....", true);
new Thread() {
public void run() {
try{
Thread.sleep(2000);
} catch (Exception e) { }
runOnUiThread(new Runnable() {
#Override
public void run() {
if (searchAdapter == null)
{
Log.e("ERROR", "No Feed Available");
return;
}
searchAdapter.setContext(context);
searchList.setAdapter(searchAdapter);
searchList.setSelection(0);
}
});
// Dismiss the Dialog
myProgressDialog.dismiss();
}
}.start();
}
}
And the SearchHandler class is simple:
public class SearchHandler extends DefaultHandler {
SearchAdapter _adapter;
SearchItem _item;
public SearchHandler()
{
}
public SearchAdapter getFeed()
{
return _adapter;
}
public void parseJSON(String data) {
// TODO Auto-generated method stub
_adapter = new SearchAdapter();
JSONArray parseArray;
try {
parseArray = new JSONArray(data);
for (int i=0; i < parseArray.length(); i++) {
SearchItem item = new SearchItem();
JSONObject jsonUser = parseArray.getJSONObject(i);
item.set_from(jsonUser.getString ("from"));
item.set_msg(jsonUser.getString("msg"));
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
No matter what I do, the handler gets called and the new items are fetched, but the list is never refreshed... Any ideas on what could be going wrong?
Well, it is a little bit difficult to follow your code, since you only have a fragment of it, and few of the really relevant bits. For example, based on your available code, your list should be forever empty, since you never associate the searchAdapter with a ListView...at least in the code you have shown.
That being said, the following lines seem particularly odd:
searchAdapter = getFeed(URL);
searchAdapter.notifyDataSetChanged();
I am going to assume that getFeed() (not shown) creates a new ListAdapter of some sort. If getFeed() is creating a new ListAdapter, there is no need to call notifyDataSetChanged() on it, as its data set hasn't changed -- it's brand new. Moreover, unless you are associating this new ListAdapter to your ListView, the new ListAdapter will have no effect.
If I'm barking up the wrong tree, consider adding lines to your sample showing the implementation of getFeed() and where you are using searchAdapter.