I am using pagination in my list view and i am displaying a progress bar(small) in list view footer when user scroll down to end of the list view.
LayoutInflater inflater = (LayoutInflater)getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.list_footer, null);
myListView.addFooter(view).
Then i am setting my adapter as follows
ProgressBar progressBar = (ProgressBar) getFooterView().findViewById(R.id.progressBar);
mAdapter = new MyAdapter(BaseActivity.getActivity(), 0, progressBar, myArrayList);
mList.setAdapter(mAdapter);
In my adapter class i am settings progress bar visibility in getView() method as follows.
if(position == MAX_RECORDS)
{
progressBar.setVisibility(View.VISIBLE);
// Some code goes here.
} else
progressBar.setVisibility(View.GONE);
But ProgressBar not disappears when list has no data to fetch. Please help me.
Set progressBar to visible state initially and use the same code itself.
try this one.Changes in this line will help you
ProgressBar progressBar = (ProgressBar)view.findViewById(R.id.progressBar);
instead of
ProgressBar progressBar = (ProgressBar) getFooterView().findViewById(R.id.progressBar);
try :
if(position == MAX_RECORDS-1)
position starts with 0
UPDATE
Just trying to understand your code here:
if(position == MAX_RECORDS-1)
{
progressBar.setVisibility(View.VISIBLE);
// Some code goes here.
}
above block will get executed when the last row is displayed. since getview is called for all rows before, and hopefully you are using convertview, the else block will not be executed again.
Net result is : dialog will be visible indefinitely.
If I am right you want to show the dialog when loading data and hide it when load completes. There are two scenarios:
you fetch data in one go
you fetch data when last row is displayed.
Can you shed some light which one of above is true?
Related
I have custom list item with 5 textviews and 1 progressbar in a recyclerview.
I want to update one Progressbar of a listItem in every second.
To achieve this I use Runnable and Handler, I have used
progressHandler.postDelayed( runnable ,1000);
In run method of runnable I have update the listItem and set in RecyclerView.Adapter subclass
this.mAdapter.refresh(position, listInfo);
Refresh method is as follows in adapter
public void refresh(int position, ListInfo item){
this.filteredData.set(position, item);
notifyItemChanged(position);
}
This works and update the custom listItem every second.
But the problem is, it also updates the 5 text views in ListItem and the list item update flicks
Is there any way to update only the Progressbar in the listItem?
Instead of updating the entire list item, what you can do is outside the adapter class instead of
this.mAdapter.refresh(position, listInfo);
Use this
View view = recyclerView.getChildAt(position - linearLayoutManager.findFirstVisibleItemPosition());// linearLayoutManager is recyclerview's layout manager
if (view != null) {
ProgressBar progressBar = (ProgressBar) view.findViewById(R.id.progress_bar);
progressBar.postDelayed( runnable ,1000);
}
In my app I am using recycler view.I want to show and hide view on particular condition.But when I scroll recycler views I am not getting expected behaviour.When I Visible a view it gets visible for other rows as well randomly.
What I understand is when it recycles it reuses view and when previous view when it gets recycled it finds the visibility of that view.How can I hide view on particular condition? here is my adapter code
#Override
public void onBindViewHolder(UrduRhymesViewHolder holder, int position) {
RhymesModel current = mUrduRhymesList.get(position);
AppUtility.setCustomFont(mContext, holder.tvUrduRhymesName, Constants.HANDLEE_REGULAR);
holder.tvUrduRhymesName.setText(current.getRhymeName());
holder.ivUrduRhymesLogo.setImageUrl(current.getThumbnailUrl(), mImageRequest);
int status = AppUtility.getFavouriteStatus(mContext, current.getRhymeName(), new UrduRhymesDb(mContext));
if (status == 0)
holder.btnFavourite.setBackgroundResource(R.mipmap.btn_star_unactive);
else
holder.btnFavourite.setBackgroundResource(R.mipmap.btn_star);
ProgressbarDetails progressbarDetails = ProgressbarDetails.getProgressDetail(current.getRhymeName());
if (progressbarDetails == null) {
progressbarDetails = new ProgressbarDetails();
progressbarDetails.prgProgressBar = holder.pbRhymeDownload;
progressbarDetails.download_btn_settings = holder.downloadButtonLayout;
} else {
progressbarDetails.prgProgressBar = holder.pbRhymeDownload;
progressbarDetails.download_btn_settings = holder.downloadButtonLayout;
holder.pbRhymeDownload.setProgress(progressbarDetails.progress);
}
ProgressbarDetails.addUpdateProgressDetail(current.getRhymeName(), progressbarDetails);
if (progressbarDetails != null && progressbarDetails.isDownloading) {
Log.e("test","downloading foe position "+position );
holder.downloadButtonLayout.setBackgroundResource(R.mipmap.btn_download);
holder.pbRhymeDownload.setVisibility(View.VISIBLE);
holder.pbRhymeDownload.setProgress(progressbarDetails.progress);
} else {
Log.e("test","should not be visible for position "+position);
holder.pbRhymeDownload.setVisibility(View.GONE);
}
}
Here progressbarDetails.isDownloading (having value true) is the criteria when I want to show my view but is else clause it is not hiding my view
Edit: Here ProgressbarDetails (Singleton )is a class keeping reference of every row of adapter's progress bar.
No direct way of hiding and unhiding recylerview childitems.
Solution:
Let us assume that the recyclerview adapter is ArrayList
Now make another arraylist (temp_list)
Scenarios:
Hide: iterate through your adapter items and remove the ones that you want to hide. Put each of these into temp_list. After iteration is over, call notifyDataSetChanged()
Show: iterate through your temp_list items and remove the ones that you want to show. Put each of these into adapter. After iteration is over, call notifyDataSetChanged()
You should add a flag in your viewHolder that indicates if this view should be displayed or not . and check this flag every time in the onBindViewHolder.
because the recyclerView reuses the same views you should make a decision depending on something special for every view in you viewHolder.
do u mean when your data has been changed?
and your layout want to change ?
adapter.notifyDataSetChanged();
I have a special question which i havent't found the answer. I can't deal with this problem.
So... is there any way to hide or show items(images) dynamically on ListView?
I mean, after tap on toolbar menu item called "Edit", on ListView next to the texts should appear images. When user click on this image, this text should be removed from ListView and database. And, after tap on "Done", images that have previously appeared should gone.
I spent all night for this and I haven't found the answer, so guys please help me!
I have this:
And want this after click on Edit:
That's part of my Adapter (extends from BaseAdapter)
public View getView(final int position, View convertView, final ViewGroup parent) {
if(convertView == null){
convertView = inflater.inflate(R.layout.list, null);
TextView textView = (TextView) convertView.findViewById(R.id.textView);
textView.setText(todo.get(position));
ImageView circleImage = (ImageView) convertView.findViewById(R.id.circleImage);
Picasso.with(mActivity).load(R.drawable.circle_image).transform(new CircleTransform()).into(circleImage);
}
if(editMode){
circleImage.setVisibility(View.GONE);
} else circleImage.setVisibility(View.VISIBLE);
return convertView;
}
public void setMode(boolean editMode){
this.editMode=editMode;
notifyDataSetChanged();
}
onOptionItemSelected from MainActivity:
else if(id == R.id.edit){
mToDoFragment = new ToDOFragment();
mFToDoFragment.setEditable(true);
invalidateOptionsMenu();
return true;
}
And, last part from ToDoFragment:
public void setEditable(boolean editable){
mFavouritesListAdapter.setMode(editable);
}
After that, I'm getting such beutiful NullPointerException :(
java.lang.NullPointerException: Attempt to invoke virtual method 'void adapters.ToDoListAdapter.setMode(boolean)' on a null object reference
Hi please follow the blow steps. I hope it will help you.
First you have flag that indicate that current mode for example the list view in edit mode or in normal mode (view mode)
After define the mode. Take the array list with your model or object. bind you array list with BaseAdapter. I guess you are using the ListView. If you are using the RecyclerView then the process or logic will remain the same.
In inside the getView(....). Define you layout using LayoutInflater
After checking the convert-view is not null and inflating the layout.
Put the logic for check the flag of mode.
Check whether the mode is edit mode or normal view mode. If edit then show the [x] icon for each row item otherwise hide/gone the image view.
If the mode is edit when click on [x] image view remove position of the model or object from the dataset that is bind with the BaseAdapter. And call notifyDatasetChanged(). This will refresh the list view and remove the item from listview.
If edit mode is complete and user click on "Done" Option from menu item. Then simply change the flag of mode from edit to done mode. call again notifyDatasetChanged() method of your BaseAdapter
That's it. You done let me know if you have any query.
A little difficult problem to describe so please be patient
i have a progress bar in every listitem of listview used to show downloading
now to update a single view i get view object of single item
now this view is passed to async task to update only that view for which downloading is in progress
it works fine untill i scroll listview
when i scroll list view progress bar is shown for some random listitem of listview
code to invoke asynctask
ListView lv = getListView();
int visiblePosition = lv.getFirstVisiblePosition();
View v = lv.getChildAt(position - visiblePosition);
v.setClickable(true);
task = new TestLoadingTask();
task.v = lv.getChildAt(position - visiblePosition);
executeAsyncTask(task, null, null, null);
on progressupdate of async task
#Override
protected void onProgressUpdate(Object... values) {
super.onProgressUpdate(values);
progress[currentposition] = (Integer)values[0];
max[currentposition] = 100;
updateprogress(currentposition,v);
}
public void updateprogress(int position,View v)
{
ProgressBar update = (ProgressBar)v.findViewById(R.id.downloadbar);
if(max!=null && max[position]!=0)
update.setMax(max[position]);
if(progress!=null)
update.setProgress(progress[position]);
TextView tv_per = (TextView) v.findViewById(R.id.percentage);
if(progress[position]==max[position])
{
tv_per.setVisibility(View.GONE);
update.setVisibility(View.GONE);
}
else
{
tv_per.setVisibility(View.VISIBLE);
tv_per.setText(progress[position]+"/"+max[position]);
update.setVisibility(View.VISIBLE);
}
}
any reference/advice/example would be greatly appreciated.
Okay, if I understood you right, your problem is that ListView's adapter doesn't create new list-items every time you scroll it, it just converts previous. So if it doesn't have special directions about some views of new visible list-item, it will draw them like in previous list-item which was at this position.
The solution is to add some flag to your list-items (like boolean isUpdating) and show progress bar at your adapter's getView method if it's true, and hide progress bar otherwise
I'm facing a very strange phenomenon. I'm using a ViewPager from the compatibility package to display profiles.
Every profile is just a ListView with custom elements in it. Every element has two states:
There is data - display it
There's no data - display place holder
Every time I swipe between profiles I reset the data within the item objects. When I remove the REST-Calls and just let the profile item empty - which should display the placeholder - all items keep blank.
What could be the problem?
EDIT:/
That's how I set the current item in the listview. The PageViewAdapter seems to be OK, if I use static content everything works perfect.
final TextView lblTitle = (TextView)convertView.findViewById(R.id.lblTitle);
final LinearLayout llContent = (LinearLayout)convertView.findViewById(R.id.llContent);
final ProfileItem item = getItem(userPosition);
String title = item.getTitle();
if(title == null || title.equals("")) {
lblTitle.setVisibility(View.GONE);
} else {
lblTitle.setText(item.getTitle());
}
if(item.getContent().getParent() != null) {
((ViewGroup)item.getContent().getParent()).removeAllViews();
}
llContent.removeAllViews();
llContent.addView(item.getContent());
The Items look all very similar like that:
#Override
public View getContent() {
if(isTextEmpty()) {
return noTextTherePlaceholder;
} else {
return view;
}
}
The effect keeps the same even if I return just view or noTextTherePlaceholder.
If I would instate new views like a TextView in the getView method everything works as expected.
With view pager you have to get all your data in your Activity.onCreate and then use that data in your ViewPagers adapter's onInstantiateItem.