I can show images in gridview normally. However, I want to use pulltorefresh functionality and I found a library to get the functionality. I am confused how to integrate my images.
Now, the gridview just shows imagelinks in the array. How can I use imageAdapter instead of arrayAdapter to show the Images?
Thanks a lot.
This is the activity class:
public final class PullToRefreshGridActivity extends Activity {
static final int MENU_SET_MODE = 0;
private LinkedList<String> mListItems;
private PullToRefreshGridView mPullRefreshGridView;
private GridView mGridView;
private ArrayAdapter<String> mAdapter;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_ptr_grid);
mPullRefreshGridView = (PullToRefreshGridView) findViewById(R.id.pull_refresh_grid);
mGridView = mPullRefreshGridView.getRefreshableView();
// Set a listener to be invoked when the list should be refreshed.
mPullRefreshGridView.setOnRefreshListener(new OnRefreshListener2<GridView>() {
#Override
public void onPullDownToRefresh(PullToRefreshBase<GridView> refreshView) {
Toast.makeText(PullToRefreshGridActivity.this, "Pull Down!", Toast.LENGTH_SHORT).show();
new GetDataTask().execute();
}
#Override
public void onPullUpToRefresh(PullToRefreshBase<GridView> refreshView) {
Toast.makeText(PullToRefreshGridActivity.this, "Pull Up!", Toast.LENGTH_SHORT).show();
new GetDataTask().execute();
}
});
mListItems = new LinkedList<String>();
TextView tv = new TextView(this);
tv.setGravity(Gravity.CENTER);
tv.setText("Empty View, Pull Down/Up to Add Items");
mPullRefreshGridView.setEmptyView(tv);
mAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, mListItems);
mGridView.setAdapter(mAdapter);
}
private class GetDataTask extends AsyncTask<Void, Void, String[]> {
#Override
protected String[] doInBackground(Void... params) {
// Simulates a background job.
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
}
return mStrings;
}
#Override
protected void onPostExecute(String[] result) {
mListItems.addFirst("Added after refresh...");
mListItems.addAll(Arrays.asList(result));
mAdapter.notifyDataSetChanged();
// Call onRefreshComplete when the list has been refreshed.
mPullRefreshGridView.onRefreshComplete();
super.onPostExecute(result);
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
menu.add(0, MENU_SET_MODE, 0,
mPullRefreshGridView.getMode() == Mode.BOTH ? "Change to MODE_PULL_DOWN"
: "Change to MODE_PULL_BOTH");
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
MenuItem setModeItem = menu.findItem(MENU_SET_MODE);
setModeItem.setTitle(mPullRefreshGridView.getMode() == Mode.BOTH ? "Change to MODE_PULL_FROM_START"
: "Change to MODE_PULL_BOTH");
return super.onPrepareOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case MENU_SET_MODE:
mPullRefreshGridView
.setMode(mPullRefreshGridView.getMode() == Mode.BOTH ? Mode.PULL_FROM_START
: Mode.BOTH);
break;
}
return super.onOptionsItemSelected(item);
}
private String[] mStrings = {"https://lh6.googleusercontent.com/-55osAWw3x0Q/URquUtcFr5I/AAAAAAAAAbs/rWlj1RUKrYI/s1024/A%252520Photographer.jpg",
"https://lh4.googleusercontent.com/--dq8niRp7W4/URquVgmXvgI/AAAAAAAAAbs/-gnuLQfNnBA/s1024/A%252520Song%252520of%252520Ice%252520and%252520Fire.jpg",
"https://lh5.googleusercontent.com/-7qZeDtRKFKc/URquWZT1gOI/AAAAAAAAAbs/hqWgteyNXsg/s1024/Another%252520Rockaway%252520Sunset.jpg",
"https://lh3.googleusercontent.com/--L0Km39l5J8/URquXHGcdNI/AAAAAAAAAbs/3ZrSJNrSomQ/s1024/Antelope%252520Butte.jpg",
"https://lh6.googleusercontent.com/-8HO-4vIFnlw/URquZnsFgtI/AAAAAAAAAbs/WT8jViTF7vw/s1024/Antelope%252520Hallway.jpg",
"https://lh4.googleusercontent.com/-WIuWgVcU3Qw/URqubRVcj4I/AAAAAAAAAbs/YvbwgGjwdIQ/s1024/Antelope%252520Walls.jpg",
"https://lh6.googleusercontent.com/-UBmLbPELvoQ/URqucCdv0kI/AAAAAAAAAbs/IdNhr2VQoQs/s1024/Apre%2525CC%252580s%252520la%252520Pluie.jpg",
"https://lh3.googleusercontent.com/-s-AFpvgSeew/URquc6dF-JI/AAAAAAAAAbs/Mt3xNGRUd68/s1024/Backlit%252520Cloud.jpg",
"https://lh5.googleusercontent.com/-bvmif9a9YOQ/URquea3heHI/AAAAAAAAAbs/rcr6wyeQtAo/s1024/Bee%252520and%252520Flower.jpg",
"https://lh5.googleusercontent.com/-n7mdm7I7FGs/URqueT_BT-I/AAAAAAAAAbs/9MYmXlmpSAo/s1024/Bonzai%252520Rock%252520Sunset.jpg",
"https://lh6.googleusercontent.com/-4CN4X4t0M1k/URqufPozWzI/AAAAAAAAAbs/8wK41lg1KPs/s1024/Caterpillar.jpg",
"https://lh3.googleusercontent.com/-rrFnVC8xQEg/URqufdrLBaI/AAAAAAAAAbs/s69WYy_fl1E/s1024/Chess.jpg",
"https://lh5.googleusercontent.com/-WVpRptWH8Yw/URqugh-QmDI/AAAAAAAAAbs/E-MgBgtlUWU/s1024/Chihuly.jpg",};
}
Create a custom Adapter, where you refresh each cell. Create an object which contains a String and Image property, in GetDataTask create an ArrayList of all those new objects and refresh your adapter.
Heres a simple example of the adapter and object
public class CustomStepsAdapter extends BaseAdapter {
private Context mContext;
private ArrayList<CustomObject> details;
private LayoutInflater mInflater;
public CustomStepsAdapter(Context aContext, ArrayList<CustomObject> data) {
this.details = data;
this.mContext = aContext;
mInflater = LayoutInflater.from(aContext);
}
public int getCount() {
return details.size();
}
public CustomObject getItem(int position) {
return details.get(position);
}
public long getItemId(int position) {
return position;
}
public View getView() {
return mInflater.inflate(R.layout.custom_step_options_cell, null);
}
public View getView(int position, View convertView, ViewGroup parent) {
final CustomObject item = getItem(position);
CustomStepCell cell = null;
if (convertView == null) {
convertView = getView();
cell = new CustomStepCell();
cell.itemName = (TextView) convertView.findViewById(R.id.option_name);
cell.image = (ImageView) convertView.findViewById(R.id.green_checkmark);
convertView.setTag(cell);
}
else
{
cell = (CustomStepCell) convertView.getTag();
}
cell.itemName.setText(item.getItemName());
cell.image = item.getImage();
return convertView;
}
public boolean isShowPrices() {
return showPrices;
}
public void setShowPrices(boolean showPrices) {
this.showPrices = showPrices;
}
public static class CustomStepCell
{
public TextView itemName;
public ImageView image;
}
}
public class CustomObject
{
private String itemName;
private ImageView image;
public CustomObject()
{
this.itemName = "";
}
public void setImage(ImageView anImage)
{
this.image = anImage;
}
public void setItemName(String anItemName)
{
this.itemName = anItemName;
}
public ImageView getImage()
{
return this.image;
}
public String getItemName()
{
return this.itemName;
}
}
Related
Here I'm trying to make a quiz application without using databases (requirement). Each question has 4 options.
I had made a class for Questions. Now, in the activity in which I want to show my data, I'm unable to get method to fetch the data from the QuestionModelClass.
I had made 2D Array but it gets more complicated to get it. Is there any way to bind 3 of the classes (QuestionModelClass, Adapter class, and Activity class)?
public class QuestionsModelClass {
private String sQuestion;
private String sRightAnswer;
private List<String> sOptions;
QuestionsModelClass(){
sQuestion = null;
sRightAnswer = null;
sOptions = null;
}
public QuestionsModelClass(String sQuestion, String sRightAnswer, List<String> sOptions) {
this.sQuestion = sQuestion;
this.sRightAnswer = sRightAnswer;
this.sOptions = sOptions;
}
public String getsQuestion() {
return sQuestion;
}
public void setsQuestion(String sQuestion) {
this.sQuestion = sQuestion;
}
public String getsRightAnswer() {
return sRightAnswer;
}
public void setsRightAnswer(String sRightAnswer) {
this.sRightAnswer = sRightAnswer;
}
public List<String> getsOptions() {
return sOptions;
}
public void setsOptions(List<String> sOptions) {
this.sOptions = sOptions;
}
}
And my Adapter Class
public class QuizAdapter extends BaseAdapter {
private Context context;
private List<QuestionsModelClass> questionClassList;
private String[][] options;
private LayoutInflater inflater;
private QuizAdapter(Context c, List<QuestionsModelClass> l){
this.context= c;
this.questionClassList = l;
inflater = LayoutInflater.from(context);
}
#Override
public int getCount() {
return questionClassList.size();
}
#Override
public Object getItem(int position) {
return null;
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
convertView = inflater.inflate(R.layout.questionpattern, parent,false);
QuestionsModelClass questions = questionClassList.get(position);
TextView quesText= convertView.findViewById(R.id.questionTextView);
RadioButton radioButtonA = convertView.findViewById(R.id.optionA);
RadioButton radioButtonB = convertView.findViewById(R.id.optionB);
RadioButton radioButtonC = convertView.findViewById(R.id.optionC);
RadioButton radioButtonD = convertView.findViewById(R.id.optionD);
return convertView;
}
And this is the Activity class in which I am trying to implement all the functions
public class QuizActivity extends Activity {
final Context context= this;
private List<QuestionsModelClass> classObject;
Button okayButton;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_quiz);
String[] question= new String[]{"Q1. ABDE", "Q2. ADDASD"};
String[][] op;
String[] right = new String[]{"abc","def"};
classObject = new ArrayList<>();
op= new String[][]{
{"a1", "2", "3", "4"},
{"b1","b2","b3","b4"}};
final Dialog dialog = new Dialog(context);
dialog.setContentView(R.layout.customdialoguebox);
dialog.show();
okayButton = (Button) dialog.findViewById(R.id.okayButton);
okayButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(QuizActivity.this,"Good Luck!", Toast.LENGTH_SHORT).show();
dialog.cancel();
}
});
}
I've been working on adapter and tried to update it with notifydatasetchanged. But the problem I face is that after i successfully update the adapter where I can see the changes have been made in the listview, it will then change back to previous data after I return from other fragment. I've heard that adapter will reuse the convert view with same data which cause the problem, but I don't know how to fix this. I've searched for the answer but couldn't find anything similar as most of the answers were all about declaring a new adapter.
Below is part of my code:
1.refresh method in fragment
public void toggleRefreshInBackground(ArrayList<HashMap<String, Object>> list) {
dialog_list.clear();
dialog_list.addAll(list);
adapter.update(list);
}
2.getView() of my adapter
public class DialogListAdapter extends BaseAdapter {
Context context;
private ImageLoader imageLoader;
private static LayoutInflater inflater;
private ArrayList<HashMap<String, Object>> member_list;
private ArrayList<HashMap<String, Object>> member_list2;
private SparseBooleanArray mSelectedItemsIds;
private ArrayList<Integer> selectedItemPosition;
//private static final int droidGreen = Color.parseColor("#A4C639");
//private BadgeView badge;
Resources res;
String sorting;
public DialogListAdapter(Context c,
ArrayList<HashMap<String, Object>>content, String temp_sorting) {
inflater=(LayoutInflater)c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
this.context=c;
this.member_list = content;
this.member_list2 = new ArrayList<>();
this.member_list2.addAll(this.member_list);
res=c.getResources();
this.sorting = temp_sorting;
mSelectedItemsIds = new SparseBooleanArray();
selectedItemPosition = new ArrayList<>();
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return member_list.size();
}
#Override
public HashMap<String, Object> getItem(int position) {
// TODO Auto-generated method stub
return member_list.get(position);
}
#Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
public void update(ArrayList<HashMap<String,Object>> obj) {
member_list2.clear();
member_list2.addAll(obj);
notifyDataSetChanged();
}
public final class DialogListItem{ // view holder
public TextView read_count;
public TextView nameView;
public TextView numberView;
public TextView statusView;
public ImageView thumb_image;
public TextView timeView;
public TextView senderView;
public ImageView tick;
//public BadgeView badge;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
int index;
if(sorting.equals("D")){
index = member_list.size()-position-1;
}else{
index = position;
}
View row = convertView;
DialogListItem dialogItem=null;
String textbuff_time = null;
String textbuff_mess = null;
String textbuff_sender = null;
if (convertView==null){
row=inflater.inflate(R.layout.dialog_list_single, null);
dialogItem=new DialogListItem();
dialogItem.read_count=(TextView)row.findViewById(R.id.readcount);
dialogItem.nameView=(TextView)row.findViewById(R.id.member_name);
dialogItem.numberView=(TextView)row.findViewById(R.id.tab2number);
dialogItem.statusView=(TextView)row.findViewById(R.id.tab2status);
dialogItem.thumb_image=(ImageView)row.findViewById(R.id.tab2image);
dialogItem.timeView=(TextView) row.findViewById(R.id.tab2date);
dialogItem.senderView=(TextView) row.findViewById(R.id.tab2sender);
dialogItem.tick = (ImageView) row.findViewById(R.id.tick);
row.setTag(dialogItem);
}
else{
dialogItem=(DialogListItem) row.getTag();
}
if (mSelectedItemsIds.get(position)) {
row.setBackgroundColor(context.getResources().getColor(R.color.item_selected));
} else {
row.setBackgroundColor(context.getResources().getColor(R.color.item_unselected));
}
HashMap<String,Object>items;
items=member_list.get(index);
dialogItem.nameView.setText((String)items.get(DBhelper.MEMBER_NAME));
dialogItem.nameView.setTypeface(null,Typeface.BOLD);
dialogItem.nameView.setSingleLine(true);
dialogItem.nameView.setMaxLines(1);
dialogItem.nameView.setEms(13);
dialogItem.nameView.setEllipsize(TruncateAt.END);
dialogItem.numberView.setText((String)items.get(DBhelper.MEMBER_NUMBER));
String textbuff=(String)items.get(DBhelper.MEMBER_LMESSAGE);
if (!TextUtils.isEmpty(textbuff)){
textbuff_time=textbuff.substring(0, 19);
textbuff_mess=textbuff.substring(20);
int bound=textbuff_mess.indexOf("½");
if(bound!=-1){
textbuff_sender=textbuff_mess.substring(0,bound);
textbuff_mess=textbuff_mess.substring(bound+2);
}
else
textbuff_sender="";
dialogItem.statusView.setText(textbuff_mess);
if (textbuff_sender.equals(context.getResources().getString(R.string.myself))) {
dialogItem.senderView.setVisibility(View.GONE);
dialogItem.tick.setVisibility(View.VISIBLE);
} else {
textbuff_sender = textbuff_sender + ": ";
dialogItem.senderView.setVisibility(View.VISIBLE);
dialogItem.senderView.setText(textbuff_sender);
dialogItem.tick.setVisibility(View.GONE);
}
try {
dialogItem.timeView.setText(Utility.relativeTime(row.getContext(), textbuff_time));
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
else{
dialogItem.statusView.setText("");
dialogItem.senderView.setText("");
dialogItem.timeView.setText("---");
}
dialogItem.statusView.setTextColor(Color.GRAY);
dialogItem.statusView.setTypeface(null,Typeface.NORMAL);
dialogItem.timeView.setTextColor(Color.GRAY);
dialogItem.timeView.setTypeface(null,Typeface.NORMAL);
dialogItem.senderView.setTextColor(Color.GRAY);
dialogItem.senderView.setTypeface(null,Typeface.NORMAL);
dialogItem.senderView.getPaint().setTextSkewX(-0.25f);
String sformat=" "+String.valueOf(items.get(DBhelper.MEMBER_SIZE))+" ";
dialogItem.read_count.setText(sformat);
int badge_number=(Integer)items.get(DBhelper.MEMBER_SIZE);
if(badge_number>0){
dialogItem.read_count.setVisibility(View.VISIBLE);
dialogItem.statusView.setTextColor(Color.BLACK);
dialogItem.statusView.setTypeface(null,Typeface.BOLD);
dialogItem.timeView.setTextColor(Color.BLACK);
dialogItem.timeView.setTypeface(null,Typeface.BOLD);
dialogItem.senderView.setTextColor(Color.BLACK);
dialogItem.senderView.setTypeface(null,Typeface.BOLD);
dialogItem.senderView.getPaint().setTextSkewX(-0.25f);
}
else{
dialogItem.read_count.setVisibility(View.GONE);
}
StringBuffer link=new StringBuffer(Register.get_current_server_address());
if(items.get(DBhelper.MEMBER_TYPE).equals(res.getString(R.string.broadcast_chat))){
dialogItem.nameView.setTextColor(row.getResources().getColor(R.color.tab4_title));
link.append("uniappSystemFile.asp");
link.append("?file=").append("broadcast.png");
//imageLoader.DisplayImage(link.toString(), dialogItem.thumb_image);
Picasso.with(context).load(link.toString()).transform(new CircleTransform()).resize(200,200).into(dialogItem.thumb_image);
dialogItem.read_count.setVisibility(View.GONE); // disable broadcast badge
}
Picasso.with(context).load(R.drawable.ic_contact).resize(200,200).into(dialogItem.thumb_image);
Picasso.with(context).load(R.drawable.ic_notif).resize(200, 200).into(dialogItem.thumb_image);
}else{
link2 = new IMService(context.getApplicationContext()).group_image_thumb_get(tab2.myphone, (String) items.get(DBhelper.MEMBER_NUMBER));
dialogItem.nameView.setTextColor(row.getResources().getColor(R.color.tab3_title));
//imageLoader.DisplayImage(link2, dialogItem.thumb_image);
Picasso.with(context).load(link2).transform(new CircleTransform()).resize(200, 200).placeholder(R.drawable.ic_group_circle_black_48dp).error(R.drawable.ic_group_circle_black_48dp).into(dialogItem.thumb_image);
}
}
public void setSearchPattern(String pattern) {
filterListByPattern(pattern.trim());
this.notifyDataSetChanged();
}
private void filterListByPattern(String searchPattern) {
member_list.clear();
for (HashMap<String,Object> info : member_list2) {
boolean add = true;
do {
if (searchPattern == null || searchPattern.equals("")) {
break;
}
if (info.get(DBhelper.MEMBER_NAME).toString().toLowerCase().contains(searchPattern)) {
break;
}
add = false;
} while (false);
if (add) {
member_list.add(info);
}
}
}
public void resetList() {
this.member_list2 = new ArrayList<HashMap<String,Object>>();
this.member_list2.addAll(this.member_list);
this.notifyDataSetChanged();
}
public void remove(Object object) {
member_list.remove(object);
notifyDataSetChanged();
}
public void toggleSelection(int position) {
selectView(position, !mSelectedItemsIds.get(position));
}
public void removeSelection() {
mSelectedItemsIds = new SparseBooleanArray();
selectedItemPosition = new ArrayList<>();
notifyDataSetChanged();
}
public void selectView(int position, boolean value) {
if (value) {
mSelectedItemsIds.put(position, value);
selectedItemPosition.add(position);
} else {
mSelectedItemsIds.delete(position);
selectedItemPosition.remove(selectedItemPosition.indexOf(position));
}
notifyDataSetChanged();
}
public int getSelectedCount() {
return mSelectedItemsIds.size();
}
public SparseBooleanArray getSelectedIds() {
return mSelectedItemsIds;
}
public ArrayList<Integer> getItemPosition() {
return selectedItemPosition;
}
}
So, my question is why would my adapter and listview show the old data after I return from other fragment to this fragment, and how to fix this?
P.S. please don't tell me to declare a new adapter like this
adapter = new MyAdapter(list);
adapter.notifyDataSetChanged();
I know it works, but it's not a good and appropriate approach since it's a heavy operation and you don't even need to use notifyDataSetChanged after declaring a new adapter.
Many thanks
Try putting setRetainInstance(true);
inside your fragment.
If above does not work then try with onSaveInstanceState() as below -
Declare at top, Parcelable state;
Save listview state, state = listview.onSaveInstanceState(); inside onpause() of fragment or manually while changing fragment.
Then inside onCreateView check state is null or not. If null then set adapter / get data, if not then set
listview.onRestoreInstanceState(state);
On the other hand, Each time you load fragment, ArrayList will start off empty. So you need to be careful to save data.
I am using a recyclerView to show a grid of movie posters. The posters are contained in a List<> along with their respective title and so on.
I implemented a searchView widget and I can successuflly get a List of matching results. But I can't hide the other ones.
As you understand I don't want to delete the irrelevant movies from the adapter or the user would not be able to see them again.
This is the code:
public class SearchUtils {
public static List<String> search(List<Show> list, String keyword){
List<String> results = new ArrayList<>();
for (Show curVal : list){
String curTitle = curVal.getTitle().toLowerCase().trim();
if (curTitle.contains(keyword)){
results.add(curTitle);
}else{
results = new ArrayList<>();
}
}
return results;
}
}
ListFragment.java
public class ListFragment extends Fragment implements LoaderManager.LoaderCallbacks<List<Show>> {
private static final String LOG_TAG = "ListFragment";
private static final String ARG_SCOPE = "com.dcs.shows.activity_to_launch";
private static final String BASE_URL = "http://api.themoviedb.org/3";
private TextView tv;
private ProgressBar pb;
private int scope;
private RecyclerView mRecyclerView;
private ShowAdapter mShowAdapter;
private SearchView mSearchView;
public static ListFragment newInstance(int target) {
Bundle args = new Bundle();
args.putInt(ARG_SCOPE, target);
ListFragment fragment = new ListFragment();
fragment.setArguments(args);
return fragment;
}
public ListFragment() {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
scope = getArguments().getInt(ARG_SCOPE);
setHasOptionsMenu(true);
Log.i(LOG_TAG, "onCreate#Scope is: " + scope);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_list, container, false);
mShowAdapter = new ShowAdapter(new ArrayList<Show>());
mRecyclerView = (RecyclerView) rootView.findViewById(R.id.recyclerView);
GridLayoutManager glm = new GridLayoutManager(getActivity(), 4);
mRecyclerView.setLayoutManager(glm);
mRecyclerView.addItemDecoration(new SpacesItemDecoration(8, getActivity()));
mRecyclerView.setAdapter(mShowAdapter);
mRecyclerView.addOnScrollListener(new EndlessRecyclerViewScrollListener(glm) {
#Override
public void onLoadMore(int page, int totalItemsCount) {
// Triggered only when new data needs to be appended to the list
// Add whatever code is needed to append new items to the bottom of the list
}
});
pb = (ProgressBar)rootView.findViewById(R.id.progress_view);
ConnectivityManager connMgr = (ConnectivityManager) getActivity().getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
if (networkInfo != null && networkInfo.isConnected()) {
// fetch data
getLoaderManager().initLoader(1, null, this);
} else {
// display error
pb.setVisibility(View.GONE);
}
return rootView;
}
List<Show> searchList;
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
getActivity().getMenuInflater().inflate(R.menu.main, menu);
final MenuItem myActionMenuItem = menu.findItem( R.id.action_search);
mSearchView = (SearchView) myActionMenuItem.getActionView();
mSearchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String s) {
if(!mSearchView.isIconified()) {
mSearchView.setIconified(true);
}
myActionMenuItem.collapseActionView();
return false;
}
#Override
public boolean onQueryTextChange(String s) {
if(s != null || !s.isEmpty()) {
for(Show movie : mShowAdapter.getList()) {
if(movie.getTitle().toLowerCase().contains(s.toLowerCase())){
mShowAdapter.add(movie);
}
mShowAdapter.notifyDataSetChanged();
}
} else {
mShowAdapter.addItemsToList(searchList, false);
}
return false;
}
});
mSearchView.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {
#Override
public void onViewDetachedFromWindow(View arg0) {
// search was detached/closed
Log.v(LOG_TAG, "Restoring list: " + searchList + " size: " + searchList.size());
mShowAdapter.addItemsToList(searchList, false);
}
#Override
public void onViewAttachedToWindow(View arg0) {
// search was opened
searchList = mShowAdapter.getList();
}
});
}
private class ShowHolder extends RecyclerView.ViewHolder {
public ImageView mImageView;
public TextView mTextView;
public ShowHolder(View itemView) {
super(itemView);
mImageView = (ImageView) itemView.findViewById(R.id.grid_item_image);
mTextView = (TextView) itemView.findViewById(R.id.grid_item_title);
}
}
private class ShowAdapter extends RecyclerView.Adapter<ShowHolder> {
private List<Show> mShows;
public ShowAdapter(List<Show> shows) {
mShows = shows;
}
public void add(Show show){
mShows.add(show);
notifyDataSetChanged();
}
public void addItemsToList(List<Show> newShows, boolean append){
if(append){
mShows.addAll(newShows);
}else {
mShows = newShows;
}
notifyDataSetChanged();
}
public void removeItemsFromList(int index){
mShows.remove(index);
notifyItemRemoved(index);
}
public List<Show> getList(){
return mShows;
}
#Override
public ShowHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(getActivity());
View rootView = inflater.inflate(R.layout.list_item_row, parent, false);
return new ShowHolder(rootView);
}
#Override
public void onBindViewHolder(ShowHolder holder, int position) {
Show currentShow = mShows.get(position);
holder.mTextView.setText(currentShow.getTitle());
Glide.with(getActivity()).load(currentShow.getImage()).into(holder.mImageView);
}
#Override
public int getItemCount() {
return mShows.size();
}
}
#Override
public Loader<List<Show>> onCreateLoader(int i, Bundle bundle) {
//start the loader with the appropriate uri
//for now it only supports movies+popular
//it will support movies+top, tv+popular, tv+top.
Uri baseUri = Uri.parse(BASE_URL);
Uri.Builder uriBuilder = baseUri.buildUpon();
uriBuilder.appendPath("movie");
uriBuilder.appendPath("popular");
uriBuilder.appendQueryParameter("api_key", QueryUtils.API_KEY);
uriBuilder.appendQueryParameter("page", Integer.valueOf(1).toString());
Log.v(LOG_TAG, "onCreateLoader#URL built: " + uriBuilder.toString());
return new ShowLoader(getActivity(), uriBuilder.toString());
}
#Override
public void onLoadFinished(Loader<List<Show>> loader, List<Show> shows) {
// Clear the adapter of previous earthquake data
clearAdapter();
// If there is a valid list of Shows, then add them to the adapter's
// data set. This will trigger the ListView to update.
if (shows != null && !shows.isEmpty()) {
mShowAdapter.addItemsToList(shows, false);
mShowAdapter.notifyDataSetChanged();
}
pb.setVisibility(View.GONE);
}
#Override
public void onLoaderReset(Loader<List<Show>> loader) {
// Loader reset, so we can clear out our existing data.
clearAdapter();
}
private void clearAdapter(){
List<Show> empty = new ArrayList<>();
mShowAdapter.addItemsToList(empty, false);
mShowAdapter.notifyDataSetChanged();
}
Thanks
You can use two lists, one with all the elements (original), and one with just queried elements (this one should use recyclerview adapter). When querying, just select from original list and add them to adapter list, then notify changes. Don't forget to clear adapter list before adding new entries.
Edit: you can try something like this on onQueryTextChange method. Adapt for your own wish.
if(s != null && !s.isEmpty()) {
for(String movie : originalList) {
if(movie.toLowerCase().contains(s.toLowerCase()){
adapter.add(movie);
}
notifyChanges();
}
}
} else { adapter.addAll(originalList); }
I have a adapter with this code:
public class LoadOrders_adapter extends BaseAdapter {
private JSONArray data;
private Context context;
public LoadOrders_adapter(JSONArray data, Context context) {
this.data = data;
this.context = context;
}
#Override
public int getCount() {
return data.length();
}
#Override
public Object getItem(int position) {
try {
return data.get(position);
} catch (JSONException e) {
e.printStackTrace();
return null;
}
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent){
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View row = inflater.inflate(R.layout.loading_orderlist, parent, false);
ImageView product_images=(ImageView) row.findViewById(R.id.product_images);
TextView Total_quantity = (TextView) row.findViewById(R.id.Total_quantity);
TextView order_status=(TextView) row.findViewById(R.id.order_status);
TextView order_date = (TextView) row.findViewById(R.id.order_date);
TextView order_id = (TextView) row.findViewById(R.id.order_id);
TextView product_Name=(TextView) row.findViewById(R.id.product_Name);
try {
JSONObject temp = data.getJSONObject(position);
Picasso.with(context).load(WebConnection.getInstance().resource_url(temp.getString("imgUrl"))).into(product_images);
Total_quantity.setText(temp.getString("Quantity"));
order_date.setText(temp.getString("Date_Sub"));
order_id.setText("#"+temp.getString("Order_ID"));
order_status.setText(temp.getString("Status"));
product_Name.setText(temp.getString("Name"));
} catch (JSONException e) {
e.printStackTrace();
}
return row;
}
}
And a class called:
public class LoadOrders extends ActionBarActivity implements Top_fragment.Top_fragmentListener {
private JSONArray data = null;
private JSONArray OrderDetails2 = null;
private ListView Normal_Orders_list;
private String previous_activity = "info.sliit.mystyle.Home";
private String title_name = "Your Normal Orders";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_view_promotional_wear);
Normal_Orders_list = (ListView)findViewById(R.id.Normal_Orders_list);
new BackgroundProcess().execute();
}
class BackgroundProcess extends AsyncTask<Void,Void,Void> {
ProgressDialog progressDialog = new ProgressDialog(LoadOrders.this);
#Override
protected void onPreExecute() {
super.onPreExecute();
progressDialog.setMessage("Loading data...");
progressDialog.setIndeterminate(false);
progressDialog.setCancelable(true);
progressDialog.show();
}
#Override
protected Void doInBackground(Void... params) {
data = WebConnection.getInstance().get_request("Loading_order_rest/orderloading/user_id/12","json");
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
progressDialog.dismiss();
BaseAdapter baseAdapter1 = new LoadOrders_adapter(data,LoadOrders.this);
Normal_Orders_list.setAdapter(baseAdapter1);
//Normal_Orders_list.setOnItemClickListener();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_customized_orders,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();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public String get_previous_activity() {
return previous_activity;
}
#Override
public String getTitle_name() {
return title_name;
}
}
I have an activity called Activity_loading_orders which has a list view called Normal_Orders_list and i have another layout called loading_orderlist which has has a RelativeLayout with some Textviews and a button. As you can see in the code the layout loading_orderlist is loaded as an list item into the Normal_Orders_list activity. What i want to do is to remove list items when the button is clicked see image http://i.imgur.com/TYAqd0t.jpg
My Jason taken from postman
<?xml version="1.0" encoding="utf-8"?>
<xml><data><datum><Order_ID>8</Order_ID><Quantity>52</Quantity><Comment>fs</Comment><Date_Sub>2015-08-27</Date_Sub><Date_Del/><Product_ID/><Customer_ID>12</Customer_ID><Status>Accepted</Status><View>Unread</View><Name>T-shirt</Name><imgUrl>\assets\images\projectpics\normalt\Edited_front.jpg</imgUrl></datum><datum><Order_ID>10</Order_ID><Quantity>45</Quantity><Comment>sf</Comment><Date_Sub>2015-08-27</Date_Sub><Date_Del/><Product_ID/><Customer_ID>12</Customer_ID><Status>Accepted</Status><View>Unread</View><Name>T-shirt</Name><imgUrl>\assets\images\projectpics\normalt\Edited_front.jpg</imgUrl></datum></data></xml>
Consider moving the JSON parsing outside of getView(). What you're going to want to do is:
Have a (preferably) List of <ParsedJsonObject> (from parsing the JSON) instead of a JsonArray
On 'cancel' click: delete item at position from the List
After deleting the item from the list, notify your adapter that it's dataset has changed: mListViewAdapter.notifyDataSetChanged();
Please note: I'm afraid you're going to have to change to a custom ArrayAdapter instead of a BaseAdapter. The reason for this is that you are using a JSONArray as the data set for the adapter. It's not a good idea to start messing with the JSON yourself, but you're going to have to remove the item from the dataset one way or another. I recommend you take a look at libraries such as gson or Genson.
Those libraries can deserialize JSON into Java objects for you. So what'd you'd end up doing:
Fetch JSON data
Deserialize JSON data into Java objects, put these objects into a List<ParsedJsonObject>
Create a new ArrayAdapter<ParsedJsonObject>
Pass along the list of ParsedJsonObjects as the dataset for the ArrayAdapter you just created.
getView() won't have to change a lot, just change where the data comes from. getView() lets you know what position you are in, and considering you passed along a List<ParsedJsonObject>, you can just do list.get(position) to return an object containing all the data.
I hope this helped!
All right, so here's what you need to do:
Create new classes: DataModel.java, Data.java, and Datum.java
Put this in them:
DataModel.java:
public class DataModel {
private Data data;
public Data getData ()
{
return data;
}
public void setData (Data data)
{
this.data = data;
}
}
Data.java:
public class Data {
private Datum[] datum;
public Datum[] getDatum ()
{
return datum;
}
public void setDatum (Datum[] datum)
{
this.datum = datum;
}
}
Datum.java:
public class Datum{
private String Name;
private String View;
private String Status;
private String Quantity;
private String Date_Sub;
private String Comment;
private String Customer_ID;
private String Order_ID;
private String imgUrl;
public String getName ()
{
return Name;
}
public void setName (String Name)
{
this.Name = Name;
}
public String getView ()
{
return View;
}
public void setView (String View)
{
this.View = View;
}
public String getStatus ()
{
return Status;
}
public void setStatus (String Status)
{
this.Status = Status;
}
public String getQuantity ()
{
return Quantity;
}
public void setQuantity (String Quantity)
{
this.Quantity = Quantity;
}
public String getDate_Sub ()
{
return Date_Sub;
}
public void setDate_Sub (String Date_Sub)
{
this.Date_Sub = Date_Sub;
}
public String getComment ()
{
return Comment;
}
public void setComment (String Comment)
{
this.Comment = Comment;
}
public String getCustomer_ID ()
{
return Customer_ID;
}
public void setCustomer_ID (String Customer_ID)
{
this.Customer_ID = Customer_ID;
}
public String getOrder_ID ()
{
return Order_ID;
}
public void setOrder_ID (String Order_ID)
{
this.Order_ID = Order_ID;
}
public String getImgUrl ()
{
return imgUrl ;
}
public void setImgUrl (String imgUrl)
{
this.imgUrl = imgUrl;
}
}
And then in your class do Data d = genson.deserialize(jsonString, DataModel.class);
Inside DataModel is a Data instance and inside that is your array of datum's
On my app I have a ListView with Checkboxes and have an adapter that extends BaseAdapterto populate the ListView. The basic function of the list is to show debts and the user can choose which ones to pay by checking the boxes, you have the total at the bottom of the list that gets updated when the user adds/removes an item. Now, some debts are related to another and if the user checks one, any other related debt should be marked as well and same if you uncheck a debt. I also have a button that should clear all the selected debts on the list, and that's where my problem is.
I keep record of the selected debts on an ArrayList and it seems to work for all the program but the clear button. When the button is pressed the selected debts list seems to be always empty. Any idea on what could be happening?
Here is my adapter:
public class ServicesFinancialStatusAdapter extends BaseAdapter implements CompoundButton.OnCheckedChangeListener{
private Context context;
private List<Debts> debtsList;
private List<Debts> selectedDebts;
private LayoutInflater inflater;
private int tabPosition;
private float total;
private OnTotalChangedListener listener;
public ServicesFinancialStatusAdapter(Context context, List<Debts> debtsList, int tabPosition) {
this.context = context;
this.debtsList = debtsList;
this.tabPosition = tabPosition;
this.total = 0;
this.inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
this.selectedDebts = new ArrayList<Debts>();
}
#Override
public int getCount() {
return debtsList.size();
}
#Override
public Object getItem(int i) {
return debtsList.get(i);
}
#Override
public long getItemId(int i) {
return i;
}
#Override
public View getView(int i, View view, ViewGroup viewGroup) {
ViewHolder holder;
if (view == null) {
holder = new ViewHolder();
view = inflater.inflate(R.layout.item_services_financial_status, viewGroup, false);
holder.concept = (TextView) view.findViewById(R.id.payment_concept);
holder.descriptionOrDate = (TextView) view.findViewById(R.id.payment_description_date);
holder.amount = (TextView) view.findViewById(R.id.payment_amount);
holder.expirationDate = (TextView) view.findViewById(R.id.payment_expiration_date);
if (tabPosition > 4) {
holder.checkBox = (CheckBox) view.findViewById(R.id.check_box);
holder.checkBox.setOnCheckedChangeListener(this);
}
view.setTag(holder);
} else
holder = (ViewHolder) view.getTag();
Debts item = debtsList.get(i);
holder.concept.setText(item.getConcept());
holder.amount.setText(item.getAmountToString());
if (item.isExpired())
holder.expirationDate.setText(context.getString(R.string.expired_status_indicator));
else
holder.expirationDate.setText(context.getString(R.string.debts_expiration_date_indicator) + item.getExpirationDate());
if (tabPosition < 3)
holder.descriptionOrDate.setText(item.getDescription());
else if (tabPosition < 5)
holder.descriptionOrDate.setText(item.getDate());
else {
holder.descriptionOrDate.setVisibility(View.GONE);
holder.checkBox.setVisibility(View.VISIBLE);
holder.checkBox.setTag(i);
holder.checkBox.setChecked(item.isSelected());
}
return view;
}
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
//Get the position of the item clicked and the data object
Integer position = (Integer) buttonView.getTag();
Debts item = debtsList.get(position);
//Change the status ob the object
item.setSelected(isChecked);
for (Debts debts : debtsList) {
//Check on the list for related objects and marks them as well
if (debts.getConceptId() == item.getRelatedDebt())
debts.setSelected(isChecked);
//Get the amount of the debt and add/remove it from
//the selectedDebts list and update the total
float amount = debts.getAmount();
if (debts.isSelected()) {
if (!selectedDebts.contains(debts)) {
selectedDebts.add(debts);
listener.onTotalChanged(addToTotal(amount), selectedDebts);
}
}
else {
if (selectedDebts.contains(debts)) {
selectedDebts.remove(debts);
listener.onTotalChanged(removeFromTotal(amount), selectedDebts);
}
}
}
//Finally update the UI
notifyDataSetChanged();
}
//Anywhere else in the code selectedDebts has the right data but here
//Here the size of the list is always 0
public void unMarkDebts() {
for (Debts debts : debtsList) {
//Get the amount of the debt and remove it from
//the selectedDebts list, set the data object as unselected
//and update the total
float amount = debts.getAmount();
if (selectedDebts.contains(debts)) {
debts.setSelected(false);
selectedDebts.remove(debts);
listener.onTotalChanged(removeFromTotal(amount), selectedDebts);
}
}
//Update the UI
notifyDataSetChanged();
}
private float addToTotal(float value) {
return total += value;
}
private float removeFromTotal(float value) {
return total -=value;
}
public interface OnTotalChangedListener{
public void onTotalChanged(float total, List<Debts> selectedDebts);
}
public void setOnTotalChangedListener(OnTotalChangedListener listener) {
this.listener = listener;
}
private class ViewHolder {
TextView concept, descriptionOrDate, amount, expirationDate;
CheckBox checkBox;
}
}
And here is my fragment code:
public class CheckoutFragment extends BaseFragment implements View.OnClickListener, ServicesFinancialStatusAdapter.OnTotalChangedListener {
public static final String TAG = CheckoutFragment.class.getSimpleName();
private List<Debts> debtsList;
private List<Debts> selectedDebts;
private ServicesFinancialStatusAdapter adapter;
private TextView totalView, positiveBalanceView;
private View noDebtsView, header, footer;
private LinearLayout mainLayout;
private float total, positiveBalance;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
debtsList = new ArrayList<Debts>();
adapter = new ServicesFinancialStatusAdapter(getActivity(), debtsList, 5);
adapter.setOnTotalChangedListener(this);
webServices = ((MainActivity) getActivity()).getNetworkInstance();
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
//Initialize the views
...
reloadData();
onTotalChanged(0, null);
return view;
}
#Override
public void onClick(View view) {
reloadData();
}
#Override
public void onTotalChanged(float total, List<Debts> selectedDebts) {
this.total = total == 0 ? total : total - positiveBalance;
this.selectedDebts = selectedDebts;
totalView.setText(getString(R.string.total_indicator) + Utilities.formatNumberAsMoney(this.total));
getActivity().invalidateOptionsMenu();
}
private void reloadData() {
debtsList.clear();
adapter = new ServicesFinancialStatusAdapter(getActivity(), debtsList, 5);
adapter.setOnTotalChangedListener(this);
loadData();
}
private void loadData() {
//Load debts from server
...
}
private void saveSelectedDebts() {
for (Debts selectedDebt : selectedDebts) {
long id = Debts.insert(getActivity(), selectedDebt);
//Log.d(TAG, "Inserted " + selectedDebt.getConcept() + " with ID " + id);
}
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
if (!((MainActivity) getActivity()).drawerIsOpen) {
inflater.inflate(R.menu.checkout, menu);
}
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.clear:
adapter.unMarkDebts();
break;
case R.id.checkout:
selectPaymentMode();
break;
}
return super.onOptionsItemSelected(item);
}
private void selectPaymentMode() {
...
}
}
The chat broke. I think one investigation could be:
Everytime you call reload, you are initiating from scracth the adapter with a new object, (call method new). Remove that line and just use the previous adapter (taking care of initiating the adapteer on onCreate). Notice that the vairable selectedDebts is local to the adapter and you are not passing it in the constructor.