Endless scrolling listview not working - java

I am developing one application. In my app I am using listview to display data from json. All the data display perfectly. But what I want is, to display first 10 objects and then loading items should show and then remaining 10 will display. My json response is as given below.
{
"interestsent":
[
{
"interestsent_user_id":369,
"name":"abc",
"profile_id":"686317",
"image":"",
},
{
"interestsent_user_id":369,
"name":"def",
"profile_id":"686318",
"image":"",
},
{
"interestsent_user_id":369,
"name":"ghi",
"profile_id":"686319",
"image":"",
},
{
"interestsent_user_id":369,
"name":"jkl",
"profile_id":"686320",
"image":"",
},
{
"interestsent_user_id":369,
"name":"mno",
"profile_id":"686321",
"image":"",
},
{
"interestsent_user_id":369,
"name":"pqr",
"profile_id":"686322",
"image":"",
},
.................
.................
]
}
Interestsent.java
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
INTEREST_SENT_URL = "http://fshdfh.com/webservice/interestsent?version=apps&user_login_id=00";
new GetData().execute("");
listview = (ListView) findViewById(R.id.listview);
Log.i("DATA", "page ::onCreate onCreate onCreate ");
mHandler = new Handler();
listview.setOnScrollListener(new EndlessScrollListener() {
#Override
public void onLoadMore(int page, int totalItemsCount) {
Log.i("DATA", "page :: " + page + " totalItemsCount :: "
+ totalItemsCount);
mProgressbar = new ProgressDialog(MainActivity.this);
mProgressbar.setMessage("Loading...");
mProgressbar.show();
count++;
if (count < maindata.size()) {
if (adapter != null) {
if (!isLoadingMore) {
isLoadingMore = true;
mHandler.postDelayed(loadMoreRunnable, 1000);
}
}
}
}
});
}
Runnable loadMoreRunnable = new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
if (count < maindata.size()) {
if (adapter != null) {
adapter.addAll(maindata.get(count));
mHandler.removeCallbacks(loadMoreRunnable);
isLoadingMore = false;
if (mProgressbar.isShowing())
mProgressbar.dismiss();
}
}
}
};
static <T> ArrayList<ArrayList<T>> chunkList(List<T> list, final int L) {
ArrayList<ArrayList<T>> parts = new ArrayList<ArrayList<T>>();
final int N = list.size();
for (int i = 0; i < N; i += L) {
parts.add(new ArrayList<T>(list.subList(i, Math.min(N, i + L))));
}
return parts;
}
private ProgressDialog mProgressbar;
public class GetData extends AsyncTask<String, String, String> {
ArrayList<Integer> data = new ArrayList<Integer>();
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
mProgressbar = new ProgressDialog(MainActivity.this);
mProgressbar.setMessage("Loading...");
mProgressbar.show();
super.onPreExecute();
}
#Override
protected String doInBackground(String... params) {
// TODO Auto-generated method stub
ArrayList<ArrayList<Integer>> data = new ArrayList<ArrayList<Integer>>();
ServiceHandler sh = new ServiceHandler();
/*try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}*/
/*for (int i = 0; i < 500; i++) {
data.add(i);
}
return null;*/
String jsonStr = sh.makeServiceCall(INTEREST_SENT_URL, ServiceHandler.GET);
Log.d("Response: ", "> " + jsonStr);
if (jsonStr != null) {
try {
JSONObject jsonObj = new JSONObject(jsonStr);
// Getting JSON Array node
interestsent = jsonObj.getJSONArray(INTEREST_SENT);
// looping through All Contacts
for (int i = 0; i < interestsent.length(); i++) {
JSONObject c = interestsent.getJSONObject(i);
// creating new HashMap
// HashMap<ArrayList<Integer> map = new HashMap<Integer>();
HashMap<String, String> map = new HashMap<String, String>();
// adding each child node to HashMap key => value
map.put(INTEREST_USER_ID, c.getString(INTEREST_USER_ID));
map.put(INTEREST_SENT_NAME,c.getString(INTEREST_SENT_NAME));
map.put(INTEREST_SENT_PROFILE, c.getString(INTEREST_SENT_PROFILE));
map.put(INTEREST_SENT_IMAGE, c.getString(INTEREST_SENT_IMAGE));
map.put(INTEREST_SENT_CAST, c.getString(INTEREST_SENT_CAST));
map.put(INTEREST_SENT_AGE, c.getString(INTEREST_SENT_AGE)+" years");
map.put(INTEREST_SENT_LOCATION, c.getString(INTEREST_SENT_LOCATION));
// adding HashList to ArrayList
data.addAll(map);
}
} catch (JSONException e) {
e.printStackTrace();
}
} else {
Log.e("ServiceHandler", "Couldn't get any data from the url");
}
return data;
}
#Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
maindata = chunkList(data, 50);
Log.i("DATA", "maindata :: " + maindata.size());
adapter = new CustomAdapterSent(maindata.get(count),
MainActivity.this);
listview.setAdapter(adapter);
if (mProgressbar.isShowing())
mProgressbar.dismiss();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, 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.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
EndlessScroolListener.java
public abstract class EndlessScrollListener implements OnScrollListener {
// The minimum amount of items to have below your current scroll position
// before loading more.
private int visibleThreshold = 5;
// The current offset index of data you have loaded
private int currentPage = 0;
// The total number of items in the dataset after the last load
private int previousTotalItemCount = 0;
// True if we are still waiting for the last set of data to load.
private boolean loading = true;
// Sets the starting page index
private int startingPageIndex = 0;
public EndlessScrollListener() {
}
public EndlessScrollListener(int visibleThreshold) {
this.visibleThreshold = visibleThreshold;
}
public EndlessScrollListener(int visibleThreshold, int startPage) {
this.visibleThreshold = visibleThreshold;
this.startingPageIndex = startPage;
this.currentPage = startPage;
}
// This happens many times a second during a scroll, so be wary of the code you place here.
// We are given a few useful parameters to help us work out if we need to load some more data,
// but first we check if we are waiting for the previous load to finish.
#Override
public void onScroll(AbsListView view,int firstVisibleItem,int visibleItemCount,int totalItemCount)
{
// If the total item count is zero and the previous isn't, assume the
// list is invalidated and should be reset back to initial state
if (totalItemCount < previousTotalItemCount) {
this.currentPage = this.startingPageIndex;
this.previousTotalItemCount = totalItemCount;
if (totalItemCount == 0) { this.loading = true; }
}
// If it’s still loading, we check to see if the dataset count has
// changed, if so we conclude it has finished loading and update the current page
// number and total item count.
if (loading && (totalItemCount > previousTotalItemCount)) {
loading = false;
previousTotalItemCount = totalItemCount;
currentPage++;
}
// If it isn’t currently loading, we check to see if we have breached
// the visibleThreshold and need to reload more data.
// If we do need to reload some more data, we execute onLoadMore to fetch the data.
if (!loading && (totalItemCount - visibleItemCount)<=(firstVisibleItem + visibleThreshold)) {
onLoadMore(currentPage + 1, totalItemCount);
loading = true;
}
}
// Defines the process for actually loading more data based on page
public abstract void onLoadMore(int page, int totalItemsCount);
#Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
// Don't take any action on changed
}
}
CustomAdapterSent.java
public class CustomAdapterSent extends BaseAdapter{
private ArrayList<Integer> mData = new ArrayList<Integer>();
private Context mContext;
private LayoutInflater inflater = null;
private static final String TAG_NAME="name";
private static final String TAG_PROFILE="profile_id";
private static final String TAG_IMAGE="image";
private static final String TAG_CAST="cast";
private static final String TAG_AGE="age";
private static final String TAG_LOCATION="location";
public CustomAdapterSent(ArrayList<Integer> mData, Context mContext) {
this.mContext = mContext;
this.mData = mData;
inflater = (LayoutInflater) mContext
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
public void addAll(ArrayList<Integer> mmData) {
this.mData.addAll(mmData);
this.notifyDataSetChanged();
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return mData.size();
}
#Override
public Object getItem(int arg0) {
// TODO Auto-generated method stub
return mData.get(arg0);
}
#Override
public long getItemId(int arg0) {
// TODO Auto-generated method stub
return 0;
}
class ViewHolder {
public TextView txtView;
TextView txtproname;
}
#Override
public View getView(int postion, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
View view = convertView;
ViewHolder holder;
if (view == null) {
view = inflater.inflate(R.layout.row_layout, null);
holder = new ViewHolder();
///holder.propic = (ImageView) convertView.findViewById(R.id.propicsent);
// holder.txtproname = (TextView) convertView.findViewById(R.id.txtpronameintsent);
//holder.txtproid = (TextView) convertView.findViewById(R.id.txtproidsent);
//holder.txtprofilecast = (TextView) convertView.findViewById(R.id.txtprofilecastintsent);
//holder.txtprofileage = (TextView) convertView.findViewById(R.id.txtprofileageintsent);
// holder.txtprofileplace = (TextView) convertView.findViewById(R.id.txtprofileplaceintsent);
holder.txtView = (TextView) view.findViewById(R.id.no_intsent);
view.setTag(holder);
} else {
holder = (ViewHolder) view.getTag();
}
Log.i("DATA", "mData.get(postion) :: " + mData.get(postion));
mData.get(postion);
// holder.txtproname.setText(listData.get(position).get(TAG_NAME));
holder.txtView.setText("Index :: " + Integer.getInteger(TAG_NAME));
return view;
}
}
XML File:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/relativemainss"
android:background="#drawable/backg"
>
<ListView android:id="#android:id/list"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:dividerHeight="1dp">
</ListView>
<TextView
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_centerInParent="true"
android:id="#+id/no_intsent"
android:textColor="#android:color/black"
android:background="#drawable/nomessaegborder" />
<Button
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="Load More"
android:id="#+id/buttoloadmoreintsent"
android:layout_below="#android:id/list" />
</RelativeLayout>

To Show only 10 item first time in ListView and show more items on scroll follow following steps:
STEP 1: Create a chunkList method which divide ArrayList in parts of size 10:
static <T> List<ArrayList<T>> chunkList(List<T> list, final int L) {
List<ArrayList<T>> parts = new ArrayList<ArrayList<T>>();
final int N = list.size();
for (int i = 0; i < N; i += L) {
parts.add(new ArrayList<T>(
list.subList(i, Math.min(N, i + L)))
);
}
return parts;
}
STEP 2: Create ArrayList and a counter which show current part :
private boolean isLoadingMore=false;
Handler mHandler = new Handler();
List<ArrayList<HashMap<String,String>>> mainArrayList;
private int count=0;
STEP 3: In onPostExecute break result and show data in ListView:
protected void onPostExecute(ArrayList<HashMap<String,String>> result) {
super.onPostExecute(result);
// your code here...
mainArrayList=chunkList(result,10);
isLoadingMore=false;
count=0;
adapter = new CustomAdapterSent(Interestsent.this,
mainArrayList.get(count));
setListAdapter(adapter);
}
}
STEP 4: Create addAll method in Adapter to append data in current data source :
public void addAll(ArrayList<HashMap<String,String>> moreData){
this.listData.addAll(moreData);
this.notifyDataSetChanged();
}
STEP 5: In onLoadMore load more data in ListView:
mHandler = new Handler();
listview.setOnScrollListener(new EndlessScrollListener() {
#Override
public void onLoadMore(int page, int totalItemsCount) {
if(count<mainArrayList.size()-1)
{
if(adapter !=null){
count++;
if(!isLoadingMore){
isLoadingMore=true;
mHandler.postDelayed(loadMoreRunnable,1000);
}
}
}
}
});
}
Runnable loadMoreRunnable = new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
if(count<mainArrayList.size())
{
if(adapter !=null){
count++;
adapter.addAll(mainArrayList.get(count));
mHandler.removeCallbacks(loadMoreRunnable);
isLoadingMore=false;
}
}
}
};

To have an AdapterView (such as a ListView or GridView) that automatically loads more items as the user scrolls through the items (aka infinite scroll). This is done by triggering a request for more data once the user crosses a threshold of remaining items before they've hit the end. Every AdapterView has support for binding to the OnScrollListener events which are triggered whenever a user scrolls through the collection. Using this system, we can define a basic EndlessScrollListener which supports most use cases by creating our own class that extends OnScrollListener.
You can find more about this in the below links :
Endless Scrolling ListView in Android
Endless Scrolling with AdapterViews
Infinite Scrolling List View
A simpler approach of adding data in a listview has been show in this SO answer: Android Endless List
Hope this helps ...

Related

Issue with RecyclerView data interchanges while scrolling

There is Scroll by loading RecyclerView(Lazy loading). When an item quantity is incremented by adding the plus button to say 10. after loading the next set of items while scrolling, The item quantity(10) is reset to 1 and 10 will be displayed for another item.
In the same sequence, if the unit is changed(by the spinner) to another unit the corresponding image will be loaded but after scrolling the unit and image will change back to initial unit.
When the image of an item is clicked, a dialog will show the details of the selected item . Sometimes the image in the dialog is correct but image of the RecyclerView is incorrect, will take time to load or will not load.
public class ArticleRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
implements Filterable {
private static final String TAG = "ArticleAdapter";
private final int VIEW_TYPE_ITEM = 0;
private final int VIEW_TYPE_LOADING = 1;
private Context context;
private Dialog articleDescriptionDialog;
private UOMOffersLIistViewAdapter uomOffersLIistViewAdapter;
private List<ArticleDetails> articleDetailsList;
private HomeActivityViewModel homeActivityViewModel;
private ItemFilter itemFilter = new ItemFilter();
private GetViewListener getViewListener;
private int lastPosition = -1;
private OnLoadMoreListener loadMoreListener;
private boolean isLoading = false, isMoreDataAvailable = true;
/*
* isLoading - to set the remote loading and complete status to fix back to back load more call
* isMoreDataAvailable - to set whether more data from server available or not.
* It will prevent useless load more request even after all the server data loaded
* */
public ArticleRecyclerViewAdapter(Context context, List<ArticleDetails> articleDetailsList
, HomeActivityViewModel homeActivityViewModel, Fragment fragment) {
this.context = context;
this.articleDetailsList = articleDetailsList;
this.homeActivityViewModel = homeActivityViewModel;
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(context);
if (viewType == VIEW_TYPE_ITEM) {
return new ItemViewHolder(inflater.inflate(R.layout.recycler_view_article_layout, parent, false));
} else {
return new LoadHolder(inflater.inflate(R.layout.item_loading_layout, parent, false));
}
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position) {
if (position >= getItemCount() - 1 && isMoreDataAvailable && !isLoading && loadMoreListener != null) {
isLoading = true;
loadMoreListener.onLoadMore();
}
if (getItemViewType(position) == VIEW_TYPE_ITEM) {
populateItemRows((ItemViewHolder) viewHolder, position);
}
//No else part needed as load holder doesn't bind any data
}
#Override
public int getItemViewType(int position) {
if (articleDetailsList.get(position).isLoading()) {
return VIEW_TYPE_LOADING;
} else {
return VIEW_TYPE_ITEM;
}
}
#Override
public int getItemCount() {
return articleDetailsList.size();
}
#Override
public long getItemId(int position) {
return position;
}
/* VIEW HOLDERS */
static class ItemViewHolder extends RecyclerView.ViewHolder {
private ImageView stockImageView, copyStockImageView;
private TextView articleNameTextView, articleStockAmountTextView, articleOfferTextView, addCartTextView;
private NumberPicker articleStockQuantityNumberPicker;
private Spinner articleStockSpinner;
private ImageButton offerInfoImageButton;
private int selectedStockItemPosition, stockQuantity;
private String articleStockQuantityString = "";
private Integer stockId;
private double stockAmount;
public ItemViewHolder(View itemView) {
super(itemView);
stockImageView = itemView.findViewById(R.id.stockImgv);
copyStockImageView = itemView.findViewById(R.id.copyStockImgv);//for fly to cart animation
articleNameTextView = itemView.findViewById(R.id.articleNameTxt);
articleStockAmountTextView = itemView.findViewById(R.id.stock_amount_txt);
articleOfferTextView = itemView.findViewById(R.id.offer_txt);
offerInfoImageButton = itemView.findViewById(R.id.offerInfo_imgbtn);
addCartTextView = itemView.findViewById(R.id.addCart_txt);
articleStockSpinner = itemView.findViewById(R.id.stock_spnr);
articleStockQuantityNumberPicker = itemView.findViewById(R.id.qty_numberPicker);
articleStockQuantityNumberPicker.setMin(1);
articleStockQuantityNumberPicker.setUnit(1);
// no limit.
// viewHolder.quantityNumberPicker.setMax(15);
}
}
static class LoadHolder extends RecyclerView.ViewHolder {
public LoadHolder(View itemView) {
super(itemView);
}
}
public void setMoreDataAvailable(boolean moreDataAvailable) {
isMoreDataAvailable = moreDataAvailable;
}
/**
* notifyDataSetChanged is final method so we can't override it
* call articleRecyclerViewAdapter.notifyDataChanged(); after update the list
*/
public void notifyDataChanged() {
notifyDataSetChanged();
isLoading = false;
}
public interface OnLoadMoreListener {
void onLoadMore();
}
public void setLoadMoreListener(OnLoadMoreListener loadMoreListener) {
this.loadMoreListener = loadMoreListener;
}
private void populateItemRows(ItemViewHolder itemViewHolder, int itemPos) {
int itemPosition = itemViewHolder.getAdapterPosition();
try {
itemViewHolder.copyStockImageView.setImageResource(R.drawable.error_logo);//initialize with error logo.
itemViewHolder.stockImageView.setImageResource(R.drawable.error_logo);//initialize with error logo.
} catch (Exception e) {
e.printStackTrace();
}
itemViewHolder.articleNameTextView.setText(articleDetailsList.get(itemPosition).getArticleName());
itemViewHolder.articleNameTextView.setSelected(true);//for marquee
itemViewHolder.articleOfferTextView.setSelected(true);//for marquee
itemViewHolder.articleStockAmountTextView.setSelected(true);//for marquee
itemViewHolder.articleOfferTextView.setVisibility(View.GONE);//for demo (now no offer and schemes).
itemViewHolder.offerInfoImageButton.setVisibility(View.GONE);//for demo
setStockSpinner(itemViewHolder, itemPosition);
itemViewHolder.offerInfoImageButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//setUOMOffersDIalog(articleDetailsList.get(itemPosition));
}
});
itemViewHolder.articleStockQuantityNumberPicker.setValueChangedListener(new ValueChangedListener() {
#Override
public void valueChanged(int quantity, ActionEnum action) {
itemViewHolder.articleStockQuantityString = Integer.valueOf(quantity).toString();
}
});
itemViewHolder.addCartTextView.setOnClickListener(new SingleClickListener() {
#Override
public void onSingleClick(View v) {
itemViewHolder.articleStockQuantityString = Integer.valueOf(itemViewHolder.articleStockQuantityNumberPicker.getValue()).toString();
itemViewHolder.stockQuantity = Integer.valueOf(itemViewHolder.articleStockQuantityString);
itemViewHolder.stockAmount = articleDetailsList.get(itemPosition).getStockDetailsList()
.get(itemViewHolder.articleStockSpinner.getSelectedItemPosition()).getmRP();
itemViewHolder.stockId = articleDetailsList.get(itemPosition).getStockDetailsList()
.get(itemViewHolder.articleStockSpinner.getSelectedItemPosition()).getStockId();
Double stockDiscountAmount = 0.0;
//TODO: 26-Oct-19 discount hardcoded.
if (itemViewHolder.stockQuantity > 0) {
addItemToCart(itemViewHolder, itemViewHolder.stockId, itemViewHolder.stockQuantity, itemViewHolder.stockAmount, stockDiscountAmount);
} else {
//not using (used for when user enter invalid quantity)
MDToast.makeText(context, FinalVariables.ToastMessages.VALID_QUANTITY
, MDToast.LENGTH_SHORT, MDToast.TYPE_WARNING).show();
}
}
});
itemViewHolder.stockImageView.setOnClickListener(new SingleClickListener() {
#Override
public void onSingleClick(View v) {
itemViewHolder.articleOfferTextView.setVisibility(View.VISIBLE);
itemViewHolder.articleOfferTextView.setText( ""+ itemViewHolder.stockQuantity);
DialogUtils.showArticleDescription(context, articleDetailsList.get(itemPosition)
, itemViewHolder.selectedStockItemPosition, new DialogButtonClickListener() {
#Override
public void positiveButtonClick() {
//do nothing.
}
});
}
});
// Here you apply the animation when the view is bound
setAnimation(itemViewHolder.itemView, itemPosition);
}
private void setStockSpinner(ItemViewHolder itemViewHolder, int itemPosition) {
UOMSpinnerAdapter uomSpinnerAdapter = new UOMSpinnerAdapter(context, R.layout.spinner_uom_layout
, StringUtils.makeUomStringArrayForSpinner(articleDetailsList.get(itemPosition).getStockDetailsList()));
itemViewHolder.articleStockSpinner.setAdapter(uomSpinnerAdapter);
// Setting OnItemClickListener to the Spinner
itemViewHolder.articleStockSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
itemViewHolder.selectedStockItemPosition = position;
itemViewHolder.articleStockAmountTextView.setText(StringUtils.addAED(StringUtils.round3(
+articleDetailsList.get(itemPosition)
.getStockDetailsList().get(position).getmRP())));
//show image from link
try {
if (!articleDetailsList.get(itemPosition).getStockDetailsList().
get(position).getStockImageDetailsList().isEmpty()) {
ImageUtils.setGlide(context, itemViewHolder.stockImageView
, articleDetailsList.get(itemPosition).getStockDetailsList().
get(position).getStockImageDetailsList().get(0).getStockImage());
//same as stockImageView but used to animate fly to cart
ImageUtils.setGlide(context, itemViewHolder.copyStockImageView
, articleDetailsList.get(itemPosition).getStockDetailsList().
get(position).getStockImageDetailsList().get(0).getStockImage());
} else {
}
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
if (articleDetailsList.get(itemPosition).getStockDetailsList().size() > 0)
itemViewHolder.articleStockAmountTextView.setText(StringUtils.addAED(
StringUtils.round3(+articleDetailsList.get(itemPosition).getStockDetailsList().get(0).getmRP())));
itemViewHolder.selectedStockItemPosition = itemViewHolder.articleStockSpinner.getSelectedItemPosition();
}
});
}
private void addItemToCart(ItemViewHolder itemViewHolder, Integer stockId, Integer stockQuantity
, Double stockAmount, Double stockDiscountAmount) {
homeActivityViewModel.isItemAlreadyCarted(stockId
, new RetrieveDataListner() {
#Override
public void onDone(Object object) {
boolean isItemAlreadyCarted = (boolean) object;
if (!isItemAlreadyCarted) {//item not in cart,add to cart.
CartedItems cartedItem = new CartedItems();
cartedItem.setStockId(stockId);
cartedItem.setStockQuantity(stockQuantity);
cartedItem.setStockAmount(stockAmount);
cartedItem.setTotalAmount(CalcUtils.calculateTotalAmount(stockQuantity, stockAmount));
cartedItem.setNetAmount(CalcUtils.calculateNetAmount(stockQuantity
, stockAmount, stockDiscountAmount));
homeActivityViewModel.insertCartedItem(cartedItem
, new InsertDbSuccessListner() {
#Override
public void onSuccess() {
//set view to call back method for fly to cart animation
if (getViewListener != null){
getViewListener.onGetView(itemViewHolder.copyStockImageView);
}
itemViewHolder.articleStockQuantityNumberPicker.setValue(1);//reset item quantity in ui.
// TODO: 21-Mar-19 check fly to cart only in home activity or not
if (context instanceof MainActivity) {
MDToast.makeText(context, TextMessages.ITEM_ADDED
, MDToast.LENGTH_SHORT, MDToast.TYPE_SUCCESS).show();
} else if (context instanceof HomeActivity) {
try {
((HomeActivity) context).setCartDetails();
} catch (Exception e) {
e.printStackTrace();
}
}
}
#Override
public void onFailure() {
}
});
} else {//item already carted,asking to add new quantity to carted quantity.
DialogUtils.showConformAlertDialog1(context, TextMessages.ITEM_ALREADY_CARTED
, TextMessages.ITEM_ALREADY_CARTED_WARNING
, StringValues.NO, StringValues.YES, new DialogButtonClickListener() {
#Override
public void positiveButtonClick() {//adding new quantity to existing quantity.
//set view to call back method for fly to cart animation
if (getViewListener != null)
getViewListener.onGetView(itemViewHolder.copyStockImageView);
homeActivityViewModel.updateCartedItemWithExistingValues(stockId, stockQuantity
, CalcUtils.calculateTotalAmount(stockQuantity, stockAmount),
CalcUtils.calculateNetAmount(stockQuantity, stockAmount, stockDiscountAmount)
, null);
itemViewHolder.articleStockQuantityNumberPicker.setValue(1);//reset item quantity in ui.
}
#Override
public void negativeButtonClick() {
}
});
}
}
});
}
/**
* Here is the key method to apply the animation
*/
private void setAnimation(View viewToAnimate, int position) {
// If the bound view wasn't previously displayed on screen, it's animated
if (position > lastPosition) {
Animation animation = AnimationUtils.loadAnimation(context, R.anim.fall_down);
viewToAnimate.startAnimation(animation);
lastPosition = position;
}
}
/**
* register listener for get article image(copyStockImageView)
* for fly to cart animation.
* the view get back to the call back(categorizedArticleFragment)).
*
* #param getViewListener
*/
public void setGetViewListener(GetViewListener getViewListener) {
this.getViewListener = getViewListener;
}
#Override
public Filter getFilter() {
return itemFilter;
}
private class ItemFilter extends Filter {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
String filterString = constraint.toString().toLowerCase();
FilterResults results = new FilterResults();
final List<ArticleDetails> list = articleDetailsList;
int count = list.size();
final List<ArticleDetails> nlist = new ArrayList<ArticleDetails>(count);
ArticleDetails filterableString;
for (int i = 0; i < count; i++) {
filterableString = list.get(i);
if (filterableString.getArticleName().toLowerCase().contains(filterString)) {
nlist.add(filterableString);
}
}
results.values = nlist;
results.count = nlist.size();
return results;
}
#SuppressWarnings("unchecked")
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
articleDetailsList = (ArrayList<ArticleDetails>) results.values;
notifyDataSetChanged();
}
}
}
Fragments onCreate
#Override
public View onCreateView(#NonNull LayoutInflater layoutInflater, ViewGroup viewGroup,
Bundle savedInstanceState) {
context = viewGroup.getContext();
parentView = layoutInflater.inflate(R.layout.fragment_article, viewGroup, false);
homeActivityViewModel = getViewModel();
articleRecyclerView = parentView.findViewById(R.id.subcategory_rcylv);
Bundle bundle = getArguments();
Integer offset = bundle.getInt(TagNames.OFFSET, 0);
Integer numberOfRows = bundle.getInt(TagNames.NUMBER_OF_ROWS, FinalVariables.GETTING_DATA_COUNT_FROM_API);
filterTypeId = bundle.getInt(TagNames.FILTER_TYPE_ID, FilterTypes.SUGGESTED);
String filterText = bundle.getString(TagNames.FILTER_TEXT, "");
Integer categoryId = bundle.getInt(TagNames.CATEGORY_ID, 0);
initArticleRecyclerViewAdapter(articleDetailsList, filterText, categoryId, offset, numberOfRows);
return parentView;
}
Initializing Adapter
private void initArticleRecyclerViewAdapter(List<ArticleDetails> articleDetailsList
, String filterText, Integer categoryId, int offset, int numberOfRows) {
articleRecyclerViewAdapter = new ArticleRecyclerViewAdapter(context, this.articleDetailsList, homeActivityViewModel, this);
articleRecyclerViewAdapter.setLoadMoreListener(new ArticleRecyclerViewAdapter.OnLoadMoreListener() {
#Override
public void onLoadMore() {
articleRecyclerView.post(new Runnable() {
#Override
public void run() {
int index = ArticleFragment.this.articleDetailsList.size();
loadMore(filterText, categoryId, index, numberOfRows);
Log.e(TAG, "scrolling,index: " + index);
}
});
//Calling loadMore function in Runnable to fix the
// java.lang.IllegalStateException: Cannot call this method while RecyclerView is computing a layout or scrolling error
}
});
articleRecyclerView.setHasFixedSize(true);
articleRecyclerView.setLayoutManager(new GridLayoutManager(context, 3));
articleRecyclerView.setAdapter(articleRecyclerViewAdapter);
load(filterText, categoryId, offset, numberOfRows);
}
Loading data
private void loadMore(String filterText, Integer categoryId, int offset, int numberOfRows) {
//add loading progress view
articleDetailsList.add(new ArticleDetails(true));
articleRecyclerViewAdapter.notifyItemInserted(articleDetailsList.size() - 1);
Integer storeId = FileUtils.getPreferenceInt(context
, Preferences.CUSTOMER_PREFERENCE, TagNames.STORE_ID);
Integer distributionChannelId = FileUtils.getPreferenceInt(context
, Preferences.CUSTOMER_PREFERENCE, TagNames.DISTRIBUTION_CHANNEL_ID);
homeActivityViewModel.getAllStockItemByCustomer(
DeviceUtils.getCredential(context, ServiceNames.GET_ALL_STOCK_ITEM_BY_CUSTOMER)
, storeId, distributionChannelId, filterTypeId, filterText, categoryId, offset, numberOfRows
, new ApiCallbackListener() {
#Override
public void onSuccess(Object object) {
try {
if (object != null) {
if (object instanceof GetAllStockItemByCustomerStatusReturn) {
//otp generation failed,
GetAllStockItemByCustomerStatusReturn getAllStockItemByCustomerStatusReturn
= (GetAllStockItemByCustomerStatusReturn) object;
showGetAllStockItemByCustomerErrorDialog(getAllStockItemByCustomerStatusReturn);
} else if (object instanceof List) {
List<GetAllStockItemByCustomerResponseData> getAllStockItemByCustomerResponseDataList
= (List<GetAllStockItemByCustomerResponseData>) object;
//remove loading view
articleDetailsList.remove(articleDetailsList.size() - 1);
List<ArticleDetails> result = new ArrayList<>();
result = homeActivityViewModel.getArticles(getAllStockItemByCustomerResponseDataList);
homeActivityViewModel.insertAllStockItemByCustomer(context,filterTypeId
, getAllStockItemByCustomerResponseDataList, null);
if (result.size() > 0) {
//add loaded data
articleDetailsList.addAll(result);
} else {//result size 0 means there is no more data available at server
articleRecyclerViewAdapter.setMoreDataAvailable(false);
//telling articleRecyclerViewAdapter to stop calling load more as no more server data available
//Toast.makeText(context, "No More Data Available", Toast.LENGTH_LONG).show();
}
articleRecyclerViewAdapter.notifyDataChanged();
//should call the custom method articleRecyclerViewAdapter.notifyDataChanged here to get the correct loading status
} else {
MDToast.makeText(context, FinalVariables.ToastMessages.SOMETHING_WENT_WRONG
, MDToast.LENGTH_SHORT, MDToast.TYPE_WARNING).show();
}
} else {
MDToast.makeText(context, FinalVariables.ToastMessages.SOMETHING_WENT_WRONG
, MDToast.LENGTH_SHORT, MDToast.TYPE_WARNING).show();
}
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
private void load(String filterText, Integer categoryId, int offset, int numberOfRows) {
Integer storeId = FileUtils.getPreferenceInt(context
, Preferences.CUSTOMER_PREFERENCE, TagNames.STORE_ID);
Integer distributionChannelId = FileUtils.getPreferenceInt(context
, Preferences.CUSTOMER_PREFERENCE, TagNames.DISTRIBUTION_CHANNEL_ID);
homeActivityViewModel.getAllStockItemByCustomer(
DeviceUtils.getCredential(context, ServiceNames.GET_ALL_STOCK_ITEM_BY_CUSTOMER)
, storeId, distributionChannelId, filterTypeId, filterText, categoryId, offset, numberOfRows
, new ApiCallbackListener() {
#Override
public void onSuccess(Object object) {
try {
if (object != null) {
if (object instanceof GetAllStockItemByCustomerStatusReturn) {
GetAllStockItemByCustomerStatusReturn getAllStockItemByCustomerStatusReturn
= (GetAllStockItemByCustomerStatusReturn) object;
showGetAllStockItemByCustomerErrorDialog(getAllStockItemByCustomerStatusReturn);
} else if (object instanceof List) {
List<GetAllStockItemByCustomerResponseData> getAllStockItemByCustomerResponseDataList
= (List<GetAllStockItemByCustomerResponseData>) object;
if (!getAllStockItemByCustomerResponseDataList.isEmpty()) {
if (offset == 0 && getAllStockItemByCustomerResponseDataList.get(0)
.getCategoryID() == StatusCodes.INVALID_CODE
&& filterTypeId == FilterTypes.SUGGESTED) {
//shows all article from store (filter type 0) if no article is mapped in suggested.
filterTypeId = FilterTypes.ALL;
load(filterText, categoryId, offset, numberOfRows);
}
}
articleDetailsList.addAll(homeActivityViewModel.getArticles(getAllStockItemByCustomerResponseDataList));
homeActivityViewModel.insertAllStockItemByCustomer(context,filterTypeId
, getAllStockItemByCustomerResponseDataList, null);
articleRecyclerViewAdapter.notifyDataChanged();
} else {
}
} else {
}
} catch (Exception e) {
e.printStackTrace();
}
}
});
}

ListView onScroll add more items

private class getArticles extends AsyncTask<Void, Void, Void> {
String url;
getArticles(String paramUrl) {
this.url = paramUrl;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
mProgressDialog = new ProgressDialog(App.this);
mProgressDialog.setMessage("Učitavanje artikala...");
mProgressDialog.setIndeterminate(false);
mProgressDialog.setCancelable(false);
mProgressDialog.show();
}
#Override
protected Void doInBackground(Void... params) {
arraylist = new ArrayList<>();
try {
Document document = Jsoup.connect(url).get();
Elements els = document.select("ul.category3 > li");
for (Element el : els) {
HashMap<String, String> map = new HashMap<>();
Elements slika = el.select("div.category3-image > a > img");
Elements naslov = el.select("div.category3-text > a.main-headline");
Element datum_noformat = el.select("div.category3-text > div.headlines-info > ul.headlines-info > li").first();
Element datum = datum_noformat.html(datum_noformat.html().replaceAll("Posted ", ""));
Elements desc = el.select("div.category3-text > p");
Elements link = el.select("div.category3-text > a.main-headline");
Element br_kom = el.select("div.category3-text > div.headlines-info > ul.headlines-info > li.comments-icon").first();
map.put("naslov", naslov.text());
map.put("datum", datum.text());
map.put("desc", desc.text());
map.put("ikona", slika.attr("src"));
map.put("link", link.attr("abs:href"));
map.put("brkom", br_kom.text());
arraylist.add(map);
}
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void result) {
listview = (ListView) findViewById(R.id.listview);
adapter = new ArtikliAdapter(App.this, arraylist);
listview.setAdapter(adapter);
mProgressDialog.dismiss();
}
I searched for a lot of codes for onlistview scrolling, but didn't know how to implement it. The problem is, when I call my asynctask, I have an url param,
like new getArticles("http://example.com").execute();
I want to implement an onscrolllistener, but it goes like this, my param is usually set to: http://www.example.com/category/categoryname/, so the second page goes like http://www.example.com/category/categoryname/page/2/, the third one goes http://www.example.com/category/categoryname/page/3/ and so on. Each page has got 7 items that need to be parsed.
How could I implement onscrolllistener, because of the url param?
Thanks in advance.
Base on this link, I have written following solution to add elements ( 30 elements at a time, i.e page size = 30) to listview asynchronously.
Create a class named EndlessListView as follows:
public class EndlessListView extends ListView implements OnScrollListener {
private View footer;
private boolean isLoading;
private EndlessListener listener;// listner
private EndlessAdapter endlessAdapter;// adapter.
private int maxNoOfElement;
public EndlessListView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
this.setOnScrollListener(this);
}
public EndlessListView(Context context, AttributeSet attrs) {
super(context, attrs);
this.setOnScrollListener(this);
}
public EndlessListView(Context context) {
super(context);
this.setOnScrollListener(this);
}
public void setListener(EndlessListener listener) {
this.listener = listener;
}
#Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
if (getAdapter() == null)
return;
if (getAdapter().getCount() == 0 || getAdapter().getCount() <= 5)
return;
int l = visibleItemCount + firstVisibleItem;
if (l >= totalItemCount && !isLoading) {
// It is time to add new data. We call the listener
Log.e("LOAD", "DATA");
isLoading = true;
listener.loadData();
}
}
public void setMaxElemnt(int maxNoOfElement) {
this.maxNoOfElement = maxNoOfElement;
}
#Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
}
public void setLoadingView(int resId) {
LayoutInflater inflater = (LayoutInflater) super.getContext()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
footer = (View) inflater.inflate(resId, null);
this.addFooterView(footer);
}
public void setAdapter(EndlessAdapter adapter) {
super.setAdapter(adapter);
this.endlessAdapter = adapter;
}
public void addNewData(List<Integer> data) {
endlessAdapter.setData(data);
endlessAdapter.notifyDataSetChanged();
isLoading = false;
}
public static interface EndlessListener {
public void loadData();
}
}
After this we have to create the adapter for it,called
EndlessAdapter
public class EndlessAdapter extends BaseAdapter {
private List<Integer> mIntegers;
private Context context;
public EndlessAdapter(Context context) {
this.context = context;
}
public void setData(List<Integer> mIntegers) {
this.mIntegers = mIntegers;
}
#Override
public int getCount() {
if (mIntegers == null)
return 0;
return mIntegers.size();
}
#Override
public Integer getItem(int index) {
if (mIntegers == null) {
return null;
} else {
return mIntegers.get(index);
}
}
#Override
public long getItemId(int arg0) {
// TODO Auto-generated method stub
return 0;
}
class ViewHolder {
TextView textView;
}
#Override
public View getView(int index, View view, ViewGroup viewGroup) {
ViewHolder holder;
if (view == null) {
holder = new ViewHolder();
view = ((LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE))
.inflate(R.layout.rows, viewGroup, false);
holder.textView = (TextView) view.findViewById(R.id.mtext);
view.setTag(holder);
} else {
holder = (ViewHolder) view.getTag();
}
holder.textView.setText(getItem(index) + "");
return view;
}
}
Now in xml of the activity we could use EndlessListView(in com.example.stackoverflow package) as follows :
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<com.example.stackoverflow.EndlessListView
android:id="#+id/endlessListView"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</RelativeLayout>
After this step we need to make following change in the MainActivity
public class MainActivity extends Activity implements EndlessListener {
private EndlessAdapter adapter;
private EndlessListView endlessListView;
private List<Integer> data;
private int gStartIndex = 30;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
endlessListView = (EndlessListView) findViewById(R.id.endlessListView);
adapter = new EndlessAdapter(this);
data = new ArrayList<Integer>();
endlessListView.setLoadingView(R.layout.footer);
// endlessListView.showFooter();
endlessListView.setListener(this);
endlessListView.setAdapter(adapter);
gStartIndex = 0;
fillData(gStartIndex);
}
private void fillData(int startIndex) {
new AsyncLoadData().execute(startIndex);
}
#Override
public void loadData() {
fillData(gStartIndex);
}
private class AsyncLoadData extends AsyncTask<Integer, Integer, Void> {
#Override
protected Void doInBackground(Integer... params) {
int gendIndex = params[0] + 30;
gStartIndex = gendIndex;
/***
* Here you could add your n/w code. To simulate the n/w comm. i am
* adding elements to list and making it sleep for few sec.
* */
for (int i = params[0]; i < gendIndex; i++) {
publishProgress(i);
}
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
#Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
data.add(values[0]);
}
#Override
protected void onPostExecute(Void result) {
endlessListView.addNewData(data);
}
}
}
This custom ScrollListView that I just found has OnBottomReachedListener which you can implement from your Activity or Fragment and receive events when user hits the bottom of the page. You would also need to track the current page and when bottom is hit to download the next page. The latest data should be added to your existing ArrayList and you should call notifyDataSetChanged() on your adapter so ListView can render the new data. You don't have to create new adapter, you just need to update the data source which is your ArrayList.
If you support orientation change you would must to save in onSaveInstanceState() your current page number so when Activity or Fragment is recreated it can continue from correct page. And you would have to keep the ArrayList data source safe of configuration changes because you don't want to downloaded it again. I would suggest using the Fragment with setRetainInstance() set to true to persist ArrayList.
Here is my custom code for keeping data around using RetainFragment:
/**
* A simple non-UI Fragment that stores a single Object
* and is retained over configuration changes.
*/
public class RetainFragment<E extends Object> extends Fragment {
/** Object for retaining. */
private E mObject;
/**
* Empty constructor as per the Fragment documentation
*/
public RetainFragment() {}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Make sure this Fragment is retained over a configuration change
setRetainInstance(true);
}
/**
* Store a single object in this Fragment.
*
* #param object The object to store
*/
public void setObject(E object) {
mObject = object;
}
/**
* Get the stored object.
*
* #return The stored object
*/
public E getObject() {
return mObject;
}
}
Example of RetainFragment usage in your Activity:
FragmentManager fm = getFragmentManager();
mRetainFragment = (RetainFragment<ArrayList>) fm.findFragmentByTag(RETAIN_FRAG);
if (mRetainFragment == null) {
mRetainFragment = new RetainFragment<>();
mRetainFragment.setObject(new ArrayList());
fm.beginTransaction().add(mRetainFragment, RETAIN_FRAG).commit();
}
ArrayList yourArrayList = mRetainFragment.getObject();
// Now your ArrayList is saved accrossed configuration changes
here what you want fist add onscrolllistner to listview
boolean loading_flage = false;
yourlistview.setOnScrollListener(new OnScrollListener() {
#Override
public void onScrollStateChanged(
AbsListView view,
int scrollState) {
// TODO Auto-generated method stub
}
#Override
public void onScroll(AbsListView view,
int firstVisibleItem,
int visibleItemCount,
int totalItemCount) {
final int lastItem = firstVisibleItem
+ visibleItemCount;
if ((lastItem == totalItemCount)
& loading_flage == false) {
//this to prevent the list to make more than one request in time
loading_flage = true;
//you can put the index for your next page here
loadMore(int page);
}
}
});
and then in loading more after loading the page set the loading with false and parse the data add it to the data that you aleardy have
//notify the adapter
adapter.notifyDataSetChanged();
loading_flage = false;
You can achieve by adding the scrolllistener on listview and check condition if list last visible item is last in ArrayList then call the asynctask with incremented page number and update the listview,mean while add the view on listview and after getting the result from server remove the loading more view from the listview like this -
AndroidListViewLoadMoreActivity.java
public class AndroidListViewLoadMoreActivity extends Activity {
ArrayList<Country> countryList;
MyCustomAdapter dataAdapter = null;
int page = 0;
boolean loadingMore = false;
View loadMoreView;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ListView listView = (ListView) findViewById(R.id.listView1);
loadMoreView = ((LayoutInflater)this
.getSystemService(Context.LAYOUT_INFLATER_SERVICE))
.inflate(R.layout.loadmore, null, false);
listView.addFooterView(loadMoreView);
//create an ArrayAdaptar from the String Array
countryList = new ArrayList<Country>();
dataAdapter = new MyCustomAdapter(this,
R.layout.country_info, countryList);
listView.setAdapter(dataAdapter);
//enables filtering for the contents of the given ListView
listView.setTextFilterEnabled(true);
listView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// When clicked, show a toast with the TextView text
Country country = (Country) parent.getItemAtPosition(position);
Toast.makeText(getApplicationContext(),
country.getCode(), Toast.LENGTH_SHORT).show();
}
});
listView.setOnScrollListener(new OnScrollListener(){
#Override
public void onScrollStateChanged(AbsListView view, int scrollState) {}
#Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
int lastInScreen = firstVisibleItem + visibleItemCount;
if((lastInScreen == totalItemCount) && !(loadingMore)){
String url = "http://10.0.2.2:8080/CountryWebService" +
"/CountryServlet";
grabURL(url);
}
}
});
String url = "http://example.com";
grabURL(url);
}
public void grabURL(String url) {
Log.v("Android Spinner JSON Data Activity", url);
new GrabURL().execute(url);
}
private class GrabURL extends AsyncTask<String, Void, String> {
private static final int REGISTRATION_TIMEOUT = 3 * 1000;
private static final int WAIT_TIMEOUT = 30 * 1000;
private final HttpClient httpclient = new DefaultHttpClient();
final HttpParams params = httpclient.getParams();
HttpResponse response;
private String content = null;
private boolean error = false;
private ProgressDialog dialog =
new ProgressDialog(AndroidListViewLoadMoreActivity.this);
protected void onPreExecute() {
dialog.setMessage("Getting your data... Please wait...");
dialog.show();
}
protected String doInBackground(String... urls) {
String URL = null;
loadingMore = true;
try {
URL = urls[0];
HttpConnectionParams.setConnectionTimeout(params, REGISTRATION_TIMEOUT);
HttpConnectionParams.setSoTimeout(params, WAIT_TIMEOUT);
ConnManagerParams.setTimeout(params, WAIT_TIMEOUT);
HttpPost httpPost = new HttpPost(URL);
//add name value pair for the country code
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
nameValuePairs.add(new BasicNameValuePair("page",String.valueOf(page)));
httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
response = httpclient.execute(httpPost);
StatusLine statusLine = response.getStatusLine();
if(statusLine.getStatusCode() == HttpStatus.SC_OK){
ByteArrayOutputStream out = new ByteArrayOutputStream();
response.getEntity().writeTo(out);
out.close();
content = out.toString();
} else{
//Closes the connection.
Log.w("HTTP1:",statusLine.getReasonPhrase());
response.getEntity().getContent().close();
throw new IOException(statusLine.getReasonPhrase());
}
} catch (ClientProtocolException e) {
Log.w("HTTP2:",e );
content = e.getMessage();
error = true;
cancel(true);
} catch (IOException e) {
Log.w("HTTP3:",e );
content = e.getMessage();
error = true;
cancel(true);
}catch (Exception e) {
Log.w("HTTP4:",e );
content = e.getMessage();
error = true;
cancel(true);
}
return content;
}
protected void onCancelled() {
dialog.dismiss();
Toast toast = Toast.makeText(AndroidListViewLoadMoreActivity.this,
"Error connecting to Server", Toast.LENGTH_LONG);
toast.setGravity(Gravity.TOP, 25, 400);
toast.show();
}
protected void onPostExecute(String content) {
dialog.dismiss();
Toast toast;
if (error) {
toast = Toast.makeText(AndroidListViewLoadMoreActivity.this,
content, Toast.LENGTH_LONG);
toast.setGravity(Gravity.TOP, 25, 400);
toast.show();
} else {
displayCountryList(content);
}
}
}
private void displayCountryList(String response){
JSONObject responseObj = null;
try {
Gson gson = new Gson();
responseObj = new JSONObject(response);
JSONArray countryListObj = responseObj.getJSONArray("countryList");
//countryList = new ArrayList<Country>();
if(countryListObj.length() == 0){
ListView listView = (ListView) findViewById(R.id.listView1);
listView.removeFooterView(loadMoreView);
}
else {
for (int i=0; i<countryListObj.length(); i++){
//get the country information JSON object
String countryInfo = countryListObj.getJSONObject(i).toString();
//create java object from the JSON object
Country country = gson.fromJson(countryInfo, Country.class);
//add to country array list
countryList.add(country);
dataAdapter.add(country);
}
page++;
dataAdapter.notifyDataSetChanged();
loadingMore = false;
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
Make MyCustomAdapter.java as adapter
private class MyCustomAdapter extends ArrayAdapter<Country> {
private ArrayList<Country> countryList;
public MyCustomAdapter(Context context, int textViewResourceId,
ArrayList<Country> countryList) {
super(context, textViewResourceId, countryList);
this.countryList = new ArrayList<Country>();
this.countryList.addAll(countryList);
}
private class ViewHolder {
TextView code;
TextView name;
TextView continent;
TextView region;
}
public void add(Country country){
Log.v("AddView", country.getCode());
this.countryList.add(country);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
Log.v("ConvertView", String.valueOf(position));
if (convertView == null) {
LayoutInflater vi = (LayoutInflater)getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
convertView = vi.inflate(R.layout.country_info, null);
holder = new ViewHolder();
holder.code = (TextView) convertView.findViewById(R.id.code);
holder.name = (TextView) convertView.findViewById(R.id.name);
holder.continent = (TextView) convertView.findViewById(R.id.continent);
holder.region = (TextView) convertView.findViewById(R.id.region);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
Country country = this.countryList.get(position);
holder.code.setText(country.getCode());
holder.name.setText(country.getName());
holder.continent.setText(country.getContinent());
holder.region.setText(country.getRegion());
return convertView;
}
}
}
Create Country.Java as pojo -
public class Country {
String code = null;
String name = null;
String continent = null;
String region = null;
Double lifeExpectancy = null;
Double gnp = null;
Double surfaceArea = null;
int population = 0;
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getContinent() {
return continent;
}
public void setContinent(String continent) {
this.continent = continent;
}
public String getRegion() {
return region;
}
public void setRegion(String region) {
this.region = region;
}
public Double getLifeExpectancy() {
return lifeExpectancy;
}
public void setLifeExpectancy(Double lifeExpectancy) {
this.lifeExpectancy = lifeExpectancy;
}
public Double getGnp() {
return gnp;
}
public void setGnp(Double gnp) {
this.gnp = gnp;
}
public Double getSurfaceArea() {
return surfaceArea;
}
public void setSurfaceArea(Double surfaceArea) {
this.surfaceArea = surfaceArea;
}
public int getPopulation() {
return population;
}
public void setPopulation(int population) {
this.population = population;
}
}
Create main.xml for main layout
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_height="fill_parent"
android:orientation="vertical">
<TextView android:layout_width="fill_parent"
android:layout_height="wrap_content" android:padding="10dp"
android:text="#string/some_text" android:textSize="20sp" />
<ListView android:id="#+id/listView1" android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</LinearLayout>
Create country_info.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="6dip" >
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:text="Code: "
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="#+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/textView1"
android:layout_below="#+id/textView1"
android:text="Name: "
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="#+id/textView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/textView2"
android:layout_below="#+id/textView2"
android:text="Continent: "
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="#+id/textView4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/textView3"
android:layout_below="#+id/textView3"
android:text="Region: "
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="#+id/continent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="#+id/textView3"
android:layout_alignBottom="#+id/textView3"
android:layout_toRightOf="#+id/textView3"
android:text="TextView" />
<TextView
android:id="#+id/region"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="#+id/textView4"
android:layout_alignBottom="#+id/textView4"
android:layout_alignLeft="#+id/continent"
android:text="TextView" />
<TextView
android:id="#+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="#+id/textView3"
android:layout_toRightOf="#+id/textView3"
android:text="TextView" />
<TextView
android:id="#+id/code"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="#+id/textView2"
android:layout_alignLeft="#+id/name"
android:text="TextView" />
</RelativeLayout>
Footer View Text - loadmore.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:gravity="center_horizontal"
android:padding="3dp"
android:layout_height="fill_parent">
<TextView
android:id="#id/android:empty"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:gravity="center"
android:padding="5dp"
android:text="Loading more data..."/>
</LinearLayout>
Don't forget to mention internet permission with -
<uses-permission android:name="android.permission.INTERNET" />
First, you need a OnScrollListener method like this:
private OnScrollListener onScrollListener() {
return 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 && pageCount < 2) {
Log.i(TAG, "loading more data");
// Execute LoadMoreDataTask AsyncTask
//It reached ListView bottom
getDataFromUrl(url_page2);
}
}
}
#Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount,
int totalItemCount) {
}
};
}
set List View scroll listener by listView.setOnScrollListener(onScrollListener());
I have a full tutorial post HERE! You can visit it!

Search Bar filter listview items [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 7 years ago.
Improve this question
I'm wanting to put a search bar to act as a filter for the data displayed in the listview.I could not find any examples that do something like that.
If someone can show me how I can do this or demonstrate an example I am very grateful.
public class ListFragment extends Fragment {
//the GridView
GridView lv;
Bitmap bitmap;
//The list that contains the menuitems (sort)
ArrayList<HashMap<String, String>> menuItems;
ProgressDialog pDialog;
View btnLoadMore;
Spinner spinner;
// Creating JSON Parser object
JSONParser jParser = new JSONParser();
//The list that contains the wallappers
ArrayList<Wallpaper> productsList;
//The adapter of the WallPaperList
WallPaperAdapter adapter;
private final String baseurl = AppConstant.BASE_URL;
String list_url;
// url to get all products list
private String url_all_products = baseurl + "get_all_products.php";
private String get_tag_products = baseurl + "get_tag_products.php";
// Flag for current page
int current_page = 0;
int max_pages;
// Prevent loading more items to the GridView twice
boolean isLoading;
//
String sort_order;
String tag;
// JSON Node names
private static final String TAG_SUCCESS = "success";
private static final String TAG_PRODUCTS = "products";
private static final String TAG_PID = "pid";
private static final String TAG_NAME = "name";
private static final String TAG_PAGE = "page";
private static final String TAG_ORDER = "order";
private static final String TAG_TAG = "tag";
private static final String TAG_THUMBURL = "url";
private static final String TAG_TOTAL_PAGE = "total_page";
// products JSONArray
JSONArray products = null;
// listener for sort order
private OnItemSelectedListener itemSelectedListener = new OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> arg0, View arg1, int position, long id) {
Log.v("Selected: ", Integer.toString(position));
if (position == 0){
sort_order = "latest";
} else if (position == 1){
sort_order = "popular";
} else if (position == 2){
sort_order = "oldest";
} else if (position == 3){
sort_order = "alphabet";
}
//"resetting the GridView"
productsList.clear();
if (adapter != null){
adapter.clear();
}
current_page = 0;
isLoading = false;
//TODO footerview is not visible
ConnectivityManager cm =
(ConnectivityManager) getActivity().getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cm.getActiveNetworkInfo();
if (netInfo != null && netInfo.isConnected()) {
new InitialLoadGridView().execute();
} else {
Toast.makeText(getActivity(), getResources().getString(R.string.no_internet), Toast.LENGTH_LONG).show();
Intent intent = new Intent(getActivity(), ImageGridActivity.class);
startActivity(intent);
}
//}
}
#Override
public void onNothingSelected(AdapterView<?> arg0) {
}
};
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.layout_listfragment, null);
lv = (GridView)view.findViewById(R.id.listView);
setRetainInstance(true);
setHasOptionsMenu(true);
return view;
}
*#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.pesquisa, menu);
super.onCreateOptionsMenu(menu,inflater);
//Pega o Componente.
SearchView mSearchView = (SearchView) menu.findItem(R.id.search)
.getActionView();
//Define um texto de ajuda:
mSearchView.setQueryHint("teste");
// exemplos de utilização:
return;
}*
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
ActionBar actions = getActivity().getActionBar();
actions.setDisplayShowTitleEnabled(false);
// Adapter
SpinnerAdapter spinadapter =
ArrayAdapter.createFromResource(getActivity(), R.array.actions,
//android.R.layout.simple_spinner_dropdown_item);
R.layout.actionbar_spinner_item);
Spinner navigationSpinner = new Spinner(getActivity());
navigationSpinner.setAdapter(spinadapter);
// Here you set navigation listener
navigationSpinner.setOnItemSelectedListener(itemSelectedListener);
actions.setCustomView(navigationSpinner);
if (getActivity().getActionBar().getCustomView().getVisibility() == View.INVISIBLE){
getActivity().getActionBar().getCustomView().setVisibility(View.VISIBLE);
}
actions.setDisplayShowCustomEnabled(true);
//ListFragment is created, so let's clear the imageloader cache
ImageLoader.getInstance().clearMemoryCache();
// Arraylist for GridView
productsList = new ArrayList<Wallpaper>();
//initialize the footer so it can be used
btnLoadMore = View.inflate(getActivity(), R.layout.footerview, null);
if ((getResources().getString(R.string.ad_visibility).equals("0"))){
// Look up the AdView as a resource and load a request.
AdView adView = (AdView) getActivity().findViewById(R.id.adView);
AdRequest adRequest = new AdRequest.Builder().build();
adView.loadAd(adRequest);
}
//TODO Implement and replace old
lv.setOnScrollListener(new OnScrollListener(){
int currentVisibleItemCount;
int currentScrollState;
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
this.currentVisibleItemCount = visibleItemCount;
}
public void onScrollStateChanged(AbsListView view, int scrollState) {
this.currentScrollState = scrollState;
this.isScrollCompleted();
}
private void isScrollCompleted() {
if (this.currentVisibleItemCount > 0 && this.currentScrollState == SCROLL_STATE_IDLE) {
/*** In this way I detect if there's been a scroll which has completed ***/
/*** do the work for load more date! ***/
if(!isLoading){
isLoading = true;
if (max_pages != current_page){
new loadMoreGridView().execute();
} else {
Log.v("INFO", "Not loading more items because everything is already showing");
}
}
}
}
});
lv.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
//String pid = ((TextView) view.findViewById(R.id.pid)).getText().toString();
String pid = productsList.get(position).getPid();
boolean singlepane = MainActivity.getPane();
if(singlepane== true){
/*
* The second fragment not yet loaded.
* Load DetailFragment by FragmentTransaction, and pass
* data from current fragment to second fragment via bundle.
*/
DetailFragment detailFragment = new DetailFragment();
Fragment myListFragment = getFragmentManager().findFragmentByTag("ListFragment");
Bundle bundle = new Bundle();
bundle.putString("TAG_PID",pid);
detailFragment.setArguments(bundle);
FragmentTransaction fragmentTransaction =
getActivity().getFragmentManager().beginTransaction();
fragmentTransaction.setCustomAnimations(
R.anim.fadein, R.anim.fadeout, R.anim.fadein, R.anim.fadeout);
//This could use some improvement, but it works, hide current fragment, show new one
fragmentTransaction.hide(myListFragment);
fragmentTransaction.add(R.id.phone_container, detailFragment);
//fragmentTransaction.show(myDetailFragment);
/*
* Add this transaction to the back stack.
* This means that the transaction will be remembered after it is
* committed, and will reverse its operation when later popped off
* the stack.
*/
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
}
}
});
}
/**
* Async Task that send a request to url
* Gets new list view data
* Appends to list view
* */
private class loadMoreGridView extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
}
protected Void doInBackground(Void... unused) {
// increment current page
current_page += +1;
// Building Parameters
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair(TAG_PAGE, Integer.toString(current_page)));
params.add(new BasicNameValuePair(TAG_ORDER, (sort_order)));
if (tag != null){
params.add(new BasicNameValuePair(TAG_TAG, (tag)));
} else {
list_url = url_all_products;
}
// getting JSON string from URL
JSONObject json = jParser.makeHttpRequest(list_url, "GET", params);
// Check your log cat for JSON reponse
Log.d("All Products: ", json.toString());
try {
// Checking for SUCCESS TAG
int success = json.getInt(TAG_SUCCESS);
if (success == 1) {
// products found
// Getting Array of Products
products = json.getJSONArray(TAG_PRODUCTS);
// looping through All Products
for (int i = 0; i < products.length(); i++) {
JSONObject c = products.getJSONObject(i);
// Storing each json item in variable
String id = c.getString(TAG_PID);
String name = c.getString(TAG_NAME);
String thumburl = c.getString(TAG_THUMBURL);
// adding items to arraylist
productsList.add(new Wallpaper(name, thumburl, id));
}
} else {
// no products found
}
} catch (JSONException e) {
e.printStackTrace();
}
getActivity().runOnUiThread(new Runnable() {
public void run() {
//OUTDATED - Listview seems to automatically keep up with the position
//get GridView current position - used to maintain scroll position
//int currentPosition = lv.getFirstVisiblePosition();
// Appending new data to menuItems ArrayList
adapter.notifyDataSetChanged();
//OUTDATED - Setting new scroll position
//lv.setSelectionFromTop(currentPosition + 1, 0);
if (current_page == max_pages){
adapter.RemoveFooterView();
} else {
adapter.setFooterView(btnLoadMore);
}
}
});
return (null);
}
protected void onPostExecute(Void unused) {
// closing progress dialog
isLoading = false;
}
}
/**
* Async Task that send a request to url
* Gets new list view data
* Appends to list view
* */
private class InitialLoadGridView extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
// Showing progress dialog before sending http request
pDialog = new ProgressDialog(
getActivity());
pDialog.setMessage(getResources().getString(R.string.wait));
pDialog.setIndeterminate(true);
pDialog.setCancelable(false);
pDialog.show();
}
protected Void doInBackground(Void... unused) {
// Building Parameters
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair(TAG_ORDER, (sort_order)));
try { tag = getActivity().getIntent().getExtras().getString("TAG"); } catch (Exception e){}
if (tag != null){
list_url = get_tag_products;
params.add(new BasicNameValuePair(TAG_TAG, (tag)));
} else {
list_url = url_all_products;
}
// getting JSON string from URL
JSONObject json = jParser.makeHttpRequest(list_url, "GET", params);
// Check your log cat for JSON reponse
Log.d("All Products: ", json.toString());
try {
// Checking for SUCCESS TAG
int success = json.getInt(TAG_SUCCESS);
max_pages = json.getInt(TAG_TOTAL_PAGE);
if (success == 1) {
// products found
// Getting Array of Products
products = json.getJSONArray(TAG_PRODUCTS);
// looping through All Products
for (int i = 0; i < products.length(); i++) {
JSONObject c = products.getJSONObject(i);
// Storing each json item in variable
String id = c.getString(TAG_PID);
String name = c.getString(TAG_NAME);
String thumburl = c.getString(TAG_THUMBURL);
// creating new HashMap
//HashMap<String, String> map = new HashMap<String, String>();
// adding items to arraylist
productsList.add(new Wallpaper(name, thumburl, id));
}
} else {
// no products found
}
} catch (JSONException e) {
e.printStackTrace();
}
getActivity().runOnUiThread(new Runnable() {
public void run() {
// Getting adapter
adapter = new WallPaperAdapter(
getActivity(), productsList);
lv.setAdapter(adapter);
current_page = 0;
if (current_page == max_pages){
adapter.RemoveFooterView();
} else {
adapter.setFooterView(btnLoadMore);
}
}
});
return (null);
}
protected void onPostExecute(Void unused) {
// closing progress dialog
pDialog.dismiss();
lv.post(new Runnable() {
public void run() {
//check if last item is visible, in that case, load some more items
if (lv.getLastVisiblePosition() == lv.getAdapter().getCount() -1 &&
lv.getChildAt(lv.getChildCount() - 1).getBottom() <= lv.getHeight() )
{
if(!isLoading){
isLoading = true;
if (max_pages != current_page){
new loadMoreGridView().execute();
Log.v("INFO", "Last Item Visible and more available so loading more");
} else {
Log.v("INFO", "Already showing max pages");
}
}
} else {
Log.v("INFO", "Last Item Not Visible, not loading more");
}
}
});
}
}
#Override
public void onHiddenChanged(boolean hidden) {
super.onHiddenChanged(hidden);
Fragment myListFragment = getFragmentManager().findFragmentByTag("ListFragment");
if (myListFragment != null && myListFragment.isVisible()) {
//VISIBLE! =)
Log.d("STATE", "Just became visible!");
getActivity().getActionBar().getCustomView().setVisibility(View.VISIBLE);
getActivity().getActionBar().setDisplayShowTitleEnabled(false);
}
}
public static int convertDpToPixels(float dp, Context context){
Resources resources = context.getResources();
return (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP,
dp,
resources.getDisplayMetrics()
);
}
public interface MyFragInterface {
public void needsHide();
}
public static boolean isInVisible(GridView scrollView, View view, Rect region, boolean relative)
{
int top = scrollView.getScrollY() + region.top;
int bottom = scrollView.getScrollY() + region.bottom;
if(!relative)
{
// If given region is not relative to scrollView
// i.e 0,0 does not point to first child left and top
top -= scrollView.getTop();
bottom -= scrollView.getTop();
}
Rect rect = new Rect(region);
rect.top = top;
rect.bottom = bottom;
Rect childRegion = new Rect(view.getLeft(), view.getTop(), view.getRight(), view.getBottom());
return Rect.intersects(childRegion, region);
}
}
Using AutoCompleteTextView for search bar is the simplest way for me, following is a sample code,hope that will help.
Layout Xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/background"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context=".MainActivity$PlaceholderFragment" >
<AutoCompleteTextView
android:id="#+id/search_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Search"
android:inputType="text"
android:lines="1"
android:textColor="#color/white"
android:textSize="20sp"
android:textStyle="bold" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/search_text"
android:background="#color/white"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin" >
<ListView
android:id="#+id/countries_list"
android:layout_width="wrap_content"
android:layout_height="match_parent" >
</ListView>
</RelativeLayout>
Fragment:
public static class PlaceholderFragment extends Fragment implements AdapterView.OnItemClickListener {
AutoCompleteTextView searchTextview;
ListView capitalList;
ArrayAdapter searchTextviewAdapter;
private View rootView;
public PlaceholderFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.fragment_main, container, false);
getActivity().setTitle(" Letsgomo");
searchTextview= (AutoCompleteTextView) rootView.findViewById(R.id.search_text);
capitalList= (ListView) rootView.findViewById(R.id.countries_list);
searchTextviewAdapter=new ArrayAdapter(getActivity(),android.R.layout.simple_list_item_1,Constants.capitals);
searchTextview.setAdapter(searchTextviewAdapter);
ArrayAdapter capitalAdapter= (ArrayAdapter) searchTextview.getAdapter();
capitalList.setAdapter(capitalAdapter);
capitalList.setOnItemClickListener(this);
return rootView;
}
}

Java.lang.Classcast Exception: java.lang.String cannot be cast to error in android

I am working on listview app and in this Activity i am use a search box but when i enter a text in search box, i got error something Java.lang.Classcast Exception: java.lang.String cannot be cast to
Activity
public class ConnectActivity extends Activity {
// unsorted list items
List<Company> mItems;
// array list to store section positions
ArrayList<Integer> mListSectionPos;
// array list to store listView data
ArrayList<String> mListItems;
// custom list view with pinned header
PinnedHeaderListView mListView;
// custom adapter
PinnedHeaderAdapter mAdaptor;
// search box
EditText mSearchView;
// loading view
ProgressBar mLoadingView;
// empty view
TextView mEmptyView;
#SuppressWarnings("unchecked")
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
overridePendingTransition(R.anim.activity_open_translate,
R.anim.activity_close_scale);
// UI elements
setupViews();
mListSectionPos = new ArrayList<Integer>();
mListItems = new ArrayList<String>();
// for handling configuration change
if (savedInstanceState != null) {
mListItems = savedInstanceState.getStringArrayList("mListItems");
mListSectionPos = savedInstanceState
.getIntegerArrayList("mListSectionPos");
if (mListItems != null && mListItems.size() > 0
&& mListSectionPos != null && mListSectionPos.size() > 0) {
setListAdaptor();
}
String constraint = savedInstanceState.getString("constraint");
if (constraint != null && constraint.length() > 0) {
mSearchView.setText(constraint);
setIndexBarViewVisibility(constraint);
}
} else {
new Poplulate().execute(mItems);
}
}
#Override
protected void onPause() {
super.onPause();
// closing transition animations
overridePendingTransition(R.anim.activity_open_scale,
R.anim.activity_close_translate);
}
private void setupViews() {
setContentView(R.layout.activity_connect);
mSearchView = (EditText) findViewById(R.id.search_view);
mLoadingView = (ProgressBar) findViewById(R.id.loading_view);
mListView = (PinnedHeaderListView) findViewById(R.id.list_view);
mListView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
TextView selectedCompanyName = (TextView) view.findViewById(R.id.row_title);
Toast.makeText(getApplicationContext(), selectedCompanyName.getText().toString(), Toast.LENGTH_SHORT).show();
Company selectedCopmanyData = new Select().from(Company.class).where("Company_Name = ?", selectedCompanyName.getText().toString().trim()).executeSingle();
startActivity(new Intent(ConnectActivity.this, CompanyActivity.class).putExtra("SELECTED_COMPANY", selectedCopmanyData));
}
});
mEmptyView = (TextView) findViewById(R.id.empty_view);
//mItems = new Select().from(Company.class).where("Bookmark = ?", true).orderBy("Company_Name ASC").execute();
mItems = new Select().from(Company.class).orderBy("Company_Name ASC").execute();
if (mItems.size() == 0) {
Company sampleData1 = new Company();
sampleData1.companyName = "MahenCO";
sampleData1.companyId = new Long(new SimpleDateFormat("ddMMyyyyHHmmSS").format(new Date()));
sampleData1.groupId = new Integer(1);
sampleData1.groupName = "Finance";
sampleData1.customerSupportNo = "12345678";
sampleData1.customerWebSite = "http://www.mahenco.com";
sampleData1.customerSupportEmail = "customersupport#mahenco.com";
sampleData1.bookmarked = false;
sampleData1.save();
Company sampleData2 = new Company();
sampleData2.companyName = "ECG Ltd";
sampleData2.companyId = new Long(new SimpleDateFormat("ddMMyyyyHHmmSS").format(new Date()));
sampleData2.groupId = new Integer(1);
sampleData2.groupName = "Insurance";
sampleData2.customerSupportNo = "18002666";
sampleData2.customerWebSite = "http://www.ecg.com";
sampleData2.customerSupportEmail = "customersupport#ecg.com";
sampleData2.bookmarked = true;
sampleData2.save();
mItems = new Select().from(Company.class).orderBy("Company_Name ASC").execute();
}
}
// I encountered an interesting problem with a TextWatcher listening for
// changes in an EditText.
// The afterTextChanged method was called, each time, the device orientation
// changed.
// An answer on Stackoverflow let me understand what was happening: Android
// recreates the activity, and
// the automatic restoration of the state of the input fields, is happening
// after onCreate had finished,
// where the TextWatcher was added as a TextChangedListener.The solution to
// the problem consisted in adding
// the TextWatcher in onPostCreate, which is called after restoration has
// taken place
//
// http://stackoverflow.com/questions/6028218/android-retain-callback-state-after-configuration-change/6029070#6029070
// http://stackoverflow.com/questions/5151095/textwatcher-called-even-if-text-is-set-before-adding-the-watcher
#Override
protected void onPostCreate(Bundle savedInstanceState) {
mSearchView.addTextChangedListener(filterTextWatcher);
super.onPostCreate(savedInstanceState);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater menuInflater = getMenuInflater();
menuInflater.inflate(R.menu.connect, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
default:
return super.onOptionsItemSelected(item);
}
}
#Override
public void onOptionsMenuClosed(Menu menu) {
openOptionsMenu();
}
private void setListAdaptor() {
// create instance of PinnedHeaderAdapter and set adapter to list view
mAdaptor = new PinnedHeaderAdapter(this, mListItems, mListSectionPos);
mListView.setAdapter(mAdaptor);
LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
// set header view
View pinnedHeaderView = inflater.inflate(R.layout.section_row_view,
mListView, false);
mListView.setPinnedHeaderView(pinnedHeaderView);
// set index bar view
IndexBarView indexBarView = (IndexBarView) inflater.inflate(
R.layout.index_bar_view, mListView, false);
indexBarView.setData(mListView, mListItems, mListSectionPos);
mListView.setIndexBarView(indexBarView);
// set preview text view
View previewTextView = inflater.inflate(R.layout.preview_view,
mListView, false);
mListView.setPreviewView(previewTextView);
// for configure pinned header view on scroll change
mListView.setOnScrollListener(mAdaptor);
}
private TextWatcher filterTextWatcher = new TextWatcher() {
public void afterTextChanged(Editable s) {
String str = s.toString();
if (mAdaptor != null && str != null)
mAdaptor.getFilter().filter(str);
}
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
public void onTextChanged(CharSequence s, int start, int before,
int count) {
}
};
Then i am entered my listFilter. This is the filter class
public class ListFilter extends Filter {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
// NOTE: this function is *always* called from a background thread,
// and
// not the UI thread.
String constraintStr = constraint.toString().toLowerCase(
Locale.getDefault());
FilterResults result = new FilterResults();
if (constraint != null && constraint.toString().length() > 0) {
ArrayList<String> filterItems = new ArrayList<String>();
synchronized (this) {
for (int i = 0; i < mItems.size(); i++) {
String item = mItems.get(i).companyName;
if (item.toLowerCase(Locale.getDefault()).startsWith(
constraintStr)) {
filterItems.add(item);
}
}
result.count = filterItems.size();
result.values = filterItems;
}
} else {
synchronized (this) {
result.count = mItems.size();
result.values = mItems;
}
}
return result;
}
#SuppressWarnings("unchecked")
#Override
protected void publishResults(CharSequence constraint,
FilterResults results) {
List<Company> filtered = (List<Company>) results.values;
setIndexBarViewVisibility(constraint.toString());
// sort array and extract sections in background Thread
new Poplulate().execute(filtered);
}
}
private void setIndexBarViewVisibility(String constraint) {
// hide index bar for search results
if (constraint != null && constraint.length() > 0) {
mListView.setIndexBarVisibility(false);
} else {
mListView.setIndexBarVisibility(true);
}
}
// sort array and extract sections in background Thread here we use
// AsyncTask
private class Poplulate extends AsyncTask<List<Company>, Void, Void> {
private void showLoading(View contentView, View loadingView,
View emptyView) {
contentView.setVisibility(View.GONE);
loadingView.setVisibility(View.VISIBLE);
emptyView.setVisibility(View.GONE);
}
private void showContent(View contentView, View loadingView,
View emptyView) {
contentView.setVisibility(View.VISIBLE);
loadingView.setVisibility(View.GONE);
emptyView.setVisibility(View.GONE);
}
private void showEmptyText(View contentView, View loadingView,
View emptyView) {
contentView.setVisibility(View.GONE);
loadingView.setVisibility(View.GONE);
emptyView.setVisibility(View.VISIBLE);
}
#Override
protected void onPreExecute() {
// show loading indicator
showLoading(mListView, mLoadingView, mEmptyView);
super.onPreExecute();
}
#Override
protected Void doInBackground(List<Company>... params) {
mListItems.clear();
mListSectionPos.clear();
List<Company> items = params[0];
if (mItems.size() > 0) {
// NOT forget to sort array
// No need for sort as it has already sorted while feathing from database
//Collections.sort(items.);
int i = 0;
String prev_section = "";
while (i < items.size()) {
String current_item = items.get(i).companyName;
String current_section = current_item.substring(0, 1)
.toUpperCase(Locale.getDefault());
if (!prev_section.equals(current_section)) {
mListItems.add(current_section);
mListItems.add(current_item);
// array list of section positions
mListSectionPos
.add(mListItems.indexOf(current_section));
prev_section = current_section;
} else {
mListItems.add(current_item);
}
i++;
}
}
return null;
}
#Override
protected void onPostExecute(Void result) {
if (!isCancelled()) {
if (mListItems.size() <= 0) {
showEmptyText(mListView, mLoadingView, mEmptyView);
} else {
setListAdaptor();
showContent(mListView, mLoadingView, mEmptyView);
}
}
super.onPostExecute(result);
}
}
#Override
protected void onSaveInstanceState(Bundle outState) {
if (mListItems != null && mListItems.size() > 0) {
outState.putStringArrayList("mListItems", mListItems);
}
if (mListSectionPos != null && mListSectionPos.size() > 0) {
outState.putIntegerArrayList("mListSectionPos", mListSectionPos);
}
String searchText = mSearchView.getText().toString();
if (searchText != null && searchText.length() > 0) {
outState.putString("constraint", searchText);
}
super.onSaveInstanceState(outState);
}
}
Thanks in advance.......
this code is adopted by Mr. Bhavy mehta on github
Here is my log cat
FATAL EXCEPTION: AsyncTask #2
java.lang.RuntimeException: An error occured while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:299)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:352)
at java.util.concurrent.FutureTask.setException(FutureTask.java:219)
at java.util.concurrent.FutureTask.run(FutureTask.java:239)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
at java.lang.Thread.run(Thread.java:856)
Caused by: java.lang.ClassCastException: java.lang.String cannot be cast to
at
and i also update my log cat
The problem here is in performFiltering.
You have defined filterItems in that method as
ArrayList<String> filterItems = new ArrayList<String>()
and you later add the filteritems to the filter result, like this:
result.count = filterItems.size();
result.values = filterItems;
(where result is of type FilterResults).
However, later you cast the value from the filterResults to be of type List < Company > in publishResults:
List<Company> filtered = (List<Company>) results.values;
This causes a runtime exception in doInBackground, when the runtime system discovers that the object that you passed it, purporting to be a List < Company > is actually a List < String >
The solution to your problem is to change filterItems to be a List of Company, not String,
and to add the mItems[i] element to it when the company name matches the constraintStr in the loop inside performFiltering.
For instance:
protected FilterResults performFiltering(CharSequence constraint) {
// NOTE: this function is *always* called from a background thread,
// and
// not the UI thread.
String constraintStr = constraint.toString().toLowerCase();
FilterResults result = new FilterResults();
if (constraint != null && constraint.toString().length() > 0) {
ArrayList<Company> filterItems = new ArrayList<Company>();
synchronized (this) {
for (int i = 0; i < mItems.size(); i++) {
Company company=mItems.get(i);
String companyName= company.companyName;
if (companyName.toLowerCase().startsWith(constraintStr)) {
filterItems.add(company);
}
}
result.count = filterItems.size();
result.values = filterItems;
}
} else {
synchronized (this) {
result.count = mItems.size();
result.values = mItems;
}
}
return result;
}
String constraintStr = constraint.toString().toLowerCase();
FilterResults result = new FilterResults(); ;
if (constraint != null && constraint.toString().length() > 0) {
ArrayList<Company> filterItems = new ArrayList<Company>();
synchronized (this) {
for (int i = 0; i < mItems.size(); i++) {
Company company=mItems.get(i);
String item= company.companyName;
if (item.toLowerCase().startsWith(constraintStr)) {
filterItems.add(company);
}
}
result.count = filterItems.size();
result.values = filterItems;
}
} else {
synchronized (this) {
result.count = mItems.size();
result.values = mItems;
}
}
return result;
You use that
You have basic issue that issue is only for object not converted in to string if you do it then its done

achartengine : how to repaint / redraw chart

i want to repaint my chart everytime i choose one of m adapter, The first time is the graph is drawn looks perfect, but when I go to the choose one and come back looks like it draws two times the same graph.
this is my source code :
public class MainActivity extends Activity {
private Button btnConnect;
private Spinner spnTime;
private String[] durationData = new String[]{
"Pilih Durasi",
"1 Minggu",
"1 Bulan",
"3 Bulan",
"9 Bulan",
"12 Bulan"
};
int period = 0;
private LinearLayout lnChart;
private ProgressDialog dialog;
public String baseURL = "http://www.abcj.com/i=";
private ArrayList<DataItem> listData;
//CHART VARIABLES
public static final String TYPE = "type";
private XYMultipleSeriesDataset mDataset = new XYMultipleSeriesDataset();
private XYMultipleSeriesRenderer mRenderer = new XYMultipleSeriesRenderer();
private XYSeries mCurrentSeries;
private XYSeriesRenderer mCurrentRenderer;
private String mDateFormat;
private GraphicalView mChartView;
private int index = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnConnect = (Button)findViewById(R.id.btnDownloadChartData);
spnTime = (Spinner)findViewById(R.id.spOptDuration);
listData = new ArrayList<DataItem>();
//CHART INITIATION
mRenderer.setApplyBackgroundColor(true);
mRenderer.setBackgroundColor(Color.argb(100, 50, 50, 50));
mRenderer.setAxisTitleTextSize(16);
mRenderer.setChartTitleTextSize(20);
mRenderer.setLabelsTextSize(15);
mRenderer.setLegendTextSize(15);
mRenderer.setMargins(new int[] { 20, 30, 15, 0 });
mRenderer.setZoomButtonsVisible(true);
mRenderer.setPointSize(10);
btnConnect.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
ArrayAdapter<String> adapter = new ArrayAdapter<String>(MainActivity.this,
android.R.layout.simple_dropdown_item_1line, durationData);
spnTime.setAdapter(adapter);
spnTime.setOnItemSelectedListener(new OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> arg0, View arg1,
int arg2, long arg3) {
// TODO Auto-generated method stub
switch (arg2+1) {
case 0:
break;
case 1:
period = 7;
break;
case 2:
period = 30;
break;
case 3:
period = 90;
break;
case 4:
period = 180;
break;
case 5:
period = 360;
break;
default:
break;
}
new LoadData(baseURL+period).execute();
}
#Override
public void onNothingSelected(AdapterView<?> arg0) {
// TODO Auto-generated method stub
}
});
}
});
}
#SuppressLint("ShowToast")
#Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
if (mChartView == null) {
lnChart = (LinearLayout) findViewById(R.id.chart);
mChartView = ChartFactory.getLineChartView(this, mDataset, mRenderer);
mRenderer.setClickEnabled(true);
mRenderer.setSelectableBuffer(100);
mChartView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
SeriesSelection seriesSelection = mChartView.getCurrentSeriesAndPoint();
double[] xy = mChartView.toRealPoint(0);
if (seriesSelection == null) {
Toast.makeText(MainActivity.this, "No chart element was clicked", Toast.LENGTH_SHORT)
.show();
}
}
});
mChartView.setOnLongClickListener(new View.OnLongClickListener() {
#SuppressLint("ShowToast")
#Override
public boolean onLongClick(View v) {
SeriesSelection seriesSelection = mChartView.getCurrentSeriesAndPoint();
if (seriesSelection == null) {
Toast.makeText(MainActivity.this, "No chart element was long pressed",
Toast.LENGTH_SHORT);
return false; // no chart element was long pressed, so let something
// else handle the event
} else {
Toast.makeText(MainActivity.this, "Chart element in series index "
+ seriesSelection.getSeriesIndex() + " data point index "
+ seriesSelection.getPointIndex() + " was long pressed", Toast.LENGTH_SHORT);
return true; // the element was long pressed - the event has been
// handled
}
}
});
mChartView.addZoomListener(new ZoomListener() {
public void zoomApplied(ZoomEvent e) {
String type = "out";
if (e.isZoomIn()) {
type = "in";
}
System.out.println("Zoom " + type + " rate " + e.getZoomRate());
}
public void zoomReset() {
System.out.println("Reset");
}
}, true, true);
mChartView.addPanListener(new PanListener() {
public void panApplied() {
System.out.println("New X range=[" + mRenderer.getXAxisMin() + ", " + mRenderer.getXAxisMax()
+ "], Y range=[" + mRenderer.getYAxisMax() + ", " + mRenderer.getYAxisMax() + "]");
}
});
lnChart.removeAllViews();
lnChart.addView(mChartView, new LayoutParams(LayoutParams.FILL_PARENT,
LayoutParams.FILL_PARENT));
} else {
mChartView.repaint();
}
}
private class LoadData extends AsyncTask<Void, Void, String>{
String url = "";
public LoadData(String url) {
// TODO Auto-generated constructor stub
this.url = url;
}
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
dialog = ProgressDialog.show(MainActivity.this, "", "Please wait");
}
#Override
protected String doInBackground(Void... params) {
// TODO Auto-generated method stub
String result = "";
try {
result = Connection.get(url);
} catch (Exception e) {
// TODO: handle exception
result = "";
Log.d("TEST CHART", e.getMessage());
}
return result;
}
#Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
fetchResponse(result.replace("\n", "").trim());
dialog.dismiss();
}
}
private void fetchResponse(String result) {
// TODO Auto-generated method stub
if (!result.equals("")) {
try {
JSONArray jsonArray = new JSONArray(result);
DataItem item = null;
for (int i = 1; i < jsonArray.length(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
item = new DataItem(jsonObject.optString("lji_invest"),
jsonObject.optDouble("persen_hmin1"),
jsonObject.optDouble("lnu_nilai"),
jsonObject.optDouble("selisih"),
jsonObject.optString("lji_id"),
jsonObject.optString("tanggal"));
listData.add(item);
}
renderChart(listData);
} catch (Exception e) {
Log.d("TEST CHART", e.getMessage());
}
}
}
private void renderChart(ArrayList<DataItem> listData) {
// TODO Auto-generated method stub
String seriesTitle = "Series Data";
XYSeries series = new XYSeries(seriesTitle);
mDataset.addSeries(series);
mCurrentSeries = series;
XYSeriesRenderer renderer = new XYSeriesRenderer();
mRenderer.addSeriesRenderer(renderer);
renderer.setFillPoints(true);
mCurrentRenderer = renderer;
for (int i = 0; i < listData.size(); i++) {
mCurrentSeries.add(listData.get(i).getInuNilai(),
listData.get(i).getPersenHmint1());
}
if (mChartView != null) {
mChartView.repaint();
}
}
#Override
protected void onRestoreInstanceState(Bundle savedState) {
super.onRestoreInstanceState(savedState);
mDataset = (XYMultipleSeriesDataset) savedState.getSerializable("dataset");
mRenderer = (XYMultipleSeriesRenderer) savedState.getSerializable("renderer");
mCurrentSeries = (XYSeries) savedState.getSerializable("current_series");
mCurrentRenderer = (XYSeriesRenderer) savedState.getSerializable("current_renderer");
mDateFormat = savedState.getString("date_format");
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putSerializable("dataset", mDataset);
outState.putSerializable("renderer", mRenderer);
outState.putSerializable("current_series", mCurrentSeries);
outState.putSerializable("current_renderer", mCurrentRenderer);
outState.putString("date_format", mDateFormat);
}
so how to repaint my chart? i hope somebody can show me where is my fault, and tell me the way to fix it
Use chartView.removeView(Graphical_View)
before setting the chart view with new values, followed by use the 'Graphical_View.repaint()' inorder to set new value to the layout
However use multirenderer.setInScroll(true);
Hard to understand the question, but I will try to guess.
In order to repaint the chart, you need to call chartView.repaint();
However, the issue you have may be fixed by having an mRenderer.setInScroll(true); call.
I slove this problem using this code
if(layout != null)
layout.removeAllViews();
layout.addView(mChartView, new LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT));
mChartView = null;

Categories

Resources