Recyclerview Inconsistency detected. Invalid view holder adapter positionViewHolder - android

In my app right now I am working with two lists. One is a List of an Object and the other the a List of Lists of the same object. I have a method in my Activity that transforms a list of Object into a List of Lists of object. And to my adapter I am passing the list of lists through this call:
mAdapter.swap(transformList(pipe.mList));
The method swap is responsible for passing the transformed list to my Adapter:
public void swap(List<List<Feed>> feedList) {
if (finallist == null) {
finallist = new ArrayList<>();
}
finallist.clear();
finallist.addAll(feedList);
}
The transformation checks if there are images in a row and puts all of them inside a single list (I am trying to implement something similar to WhatsApp image grouping). So I have a bunch of messages, they can be text messages, files, images, etc. In case of the last one, I group them in a single list.
Let me give a scenario as an example:
I have four images and 1 text message in my original array. The transformation puts all the four images into a single List of objects and de text message in another list of objects (both of them are inserted in my list of lists).
I thought about two ways to handle this transformation: 1 - do it inside the Adapter and 2 - do it in my Activity and pass the modified list to the Adapter. Each one of this solutions generated a different problem.
By following the steps in 1, I was able to display all of the content almost in the way I wanted. The grouping was working just fine! The problem is that if the original array had a length equals to 30, and the transformed array's length was decreased to 12. The RecyclerView would show all of the remaining 18 items as empty states (so after the transformation it wasn't handling the removing items properly).
By following the steps in 2, I was not able to display all of the content. Just the first element of my array. And I would get a IndexOutOfBoundsException in RecyclerView happens java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid view holder adapter positionViewHolder error message. But I was not able to identify the problem. I checked many questions here and none of them helped me.
This is my Adapter class:
public class FeedAdapter extends BaseSkeletonAdapter<Feed> implements FeedHolder.FeedHolderListener{
private static final int HOLDER_COMMENT = 1;
private static final int HOLDER_IMAGE = 2;
private static final int HOLDER_FILE = 3;
private static final int HOLDER_AUDIO = 4;
private static final int HOLDER_MARKER = 5;
private static final int HOLDER_EMPTY = 6;
private static final int HOLDER_GROUP = 7;
private final FeedItemListener mListener;
private final int mAvatarSize;
private final String mUserId;
private final int mPictureSize;
private final int mSkeletonColor;
public static List<List<Feed>> finallist;
public FeedAdapter(FeedItemListener listener, String userId, int avatarSize, int pictureSize, int skeletonColor) {
super(2);
mListener = listener;
mUserId = userId;
mAvatarSize = avatarSize;
mPictureSize = pictureSize;
mSkeletonColor = skeletonColor;
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
switch (viewType){
case HOLDER_COMMENT:
case HOLDER_IMAGE:
case HOLDER_FILE:
case HOLDER_MARKER:
case HOLDER_AUDIO:
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.adapter_feed, parent, false);
return new FeedHolder(view, this, mPictureSize);
case HOLDER_GROUP:
System.out.println("É um grupo!!!");
View viewGroup = LayoutInflater.from(parent.getContext()).inflate(R.layout.adapter_feed_group,parent,false);
return new FeedHolder(viewGroup, this, mPictureSize);
case HOLDER_EMPTY:
default:
View empty = LayoutInflater.from(parent.getContext()).inflate(R.layout.adapter_empty, parent, false);
return new EmptyPlaceholderViewHolder(empty, R.string.placeholder_feed_empty_title, R.string.placeholder_feed_empty_description, R.drawable.ic_feed_placeholder);
}
}
#Override
protected void onBind(RecyclerView.ViewHolder holder, int position) {
if(!(holder instanceof EmptyPlaceholderViewHolder)){
//Feed feed = finallist.get(position).get(0);
if (holder instanceof FeedHolder) {
if (position < finallist.size()) {
if (mUserId.equals(finallist.get(position).get(0).getCreatedById())) {
((FeedHolder) holder).onBind(finallist.get(position), mUserId, mAvatarSize);
} else {
((FeedHolder) holder).onBind(finallist.get(position), mUserId, mAvatarSize);
}
}
}
}
}
#Override
protected void onBind(RecyclerView.ViewHolder holder, int position, List<Object> payloads) {
if (payloads.isEmpty()) {
onBindViewHolder(holder, position);
}else {
if (holder instanceof FeedHolder) {
((FeedHolder) holder).onBind(finallist.get(position), payloads, mUserId, mAvatarSize);
}
}
}
#Override
protected void setHolderSkeleton(RecyclerView.ViewHolder holder) {
if (holder instanceof FeedHolder) {
((FeedHolder) holder).setHolderSkeleton(R.drawable.rounded_skeleton, mSkeletonColor);
}
}
#Override
protected void clearHolderSkeleton(RecyclerView.ViewHolder holder) {
if (holder instanceof FeedHolder) {
((FeedHolder) holder).clearHolderSkeleton();
}
}
#Override
public int getItemViewType(int position) {
if(mSkeletonMode){
return HOLDER_COMMENT;
} if (finallist != null && finallist.size() > 0 && position >= 0 && position < finallist.size()) {
System.out.println("Tamanho total: " + finallist.size());
if (finallist.get(position).size() > 1) {
System.out.println("Tamanho do grupo: " + finallist.get(position).size());
return HOLDER_GROUP;
} else {
Feed feed = finallist.get(position).get(0);
if (feed != null) {
String type = feed.getFeedType();
if (type != null) {
switch (type) {
case FEED_IMAGE:
return HOLDER_IMAGE;
case FEED_AUDIO:
return HOLDER_AUDIO;
case FEED_FILE:
return HOLDER_FILE;
case FEED_MARKER:
return HOLDER_MARKER;
case FEED_COMMENT:
default:
return HOLDER_COMMENT;
}
}
}
}
return HOLDER_COMMENT;
}else {
System.out.println("Tá vazia!");
return HOLDER_EMPTY;
}
}
public List<Feed> getItems() {
return returnList(finallist);
}
public List<List<Feed>> getListItems() {
return finallist;
}
public void swap(List<List<Feed>> feedList) {
if (finallist == null) {
finallist = new ArrayList<>();
}
finallist.clear();
finallist.addAll(feedList);
}
#Override
public void toggleLike(final int pos){
if(mListener != null && pos >= 0 && pos < finallist.size()){
mListener.toggleLike(finallist.get(pos).get(0));
}
}
#Override
public void onLongClick(final int pos, final View v) {
if (mListener != null && pos >= 0 && pos < finallist.size()) {
mListener.onLongClick(finallist.get(pos).get(0), v);
}
}
#Override
public int onAudioActionClicked(final int pos, final int progress) {
if (mListener != null) {
return mListener.onAudioActionClicked(pos, finallist.get(pos).get(0), progress);
}else {
return 0;
}
}
#Override
public void onClick(int pos) {
if (finallist!=null && pos >= 0 && pos<finallist.size()) {
Feed feed = finallist.get(pos).get(0);
if (feed != null && mListener != null) {
mListener.onClick(feed);
}
}
}
public interface FeedItemListener {
void toggleLike(#NonNull Feed feed);
void onLongClick(#NonNull Feed feed, #NonNull View v);
void onClick(#NonNull Feed feed);
int onAudioActionClicked(int pos, #NonNull Feed feed, final int progress);
}
private void transformList(List<Feed> mItems) {
finallist = new ArrayList<>();
for (int i = 0; i< mItems.size();i++) {
List<Feed> feed = new ArrayList<>();
feed.add(mItems.get(i));
finallist.add(feed);
}
int j = 0;
List<String> list = new ArrayList<>();
List<Integer> indexList = new ArrayList<>();
//System.out.println("Tamanho: " + mItems.size());
for (int i = 0; i < mItems.size(); i++) {
if (!mItems.get(i).getFeedType().equals("filePicture")) {
if (j >= 4) {
String temp = "";
for (int k = 0; k < j; k++) {
temp = temp + "->" + Integer.toString(i - (k+1));
if (k != 0) {
finallist.get(i - 1).add(finallist.get(i - (k + 1)).get(0));
indexList.add(i - (k+1));
}
}
list.add(temp);
}
j = 0;
} else {
j = j + 1;
}
if (i == mItems.size()-1) {
//System.out.println("Imagem por ultimo!");
if (j >= 4) {
//System.out.println("Grupo vem por ultimo!");
String temp = "";
for (int k = 0; k < j; k++) {
temp = temp + "->" + Integer.toString(i - (k));
if (k != 0) {
finallist.get(i).add(finallist.get(i - (k)).get(0));
indexList.add(i - (k));
}
}
list.add(temp);
}
}
}
Collections.sort(indexList);
int aux = 0;
for (int i = 0; i < indexList.size();i++) {
//System.out.println("Valor da posição: " + indexList.get(i)+ "\nTipo: "+ finallist.get((indexList.get(i).intValue())+aux).get(0).getFeedType()
// +"\nValor da posição + i: " + (indexList.get(i)+aux) + "\nAux: " + aux);
finallist.remove((indexList.get(i).intValue())+aux);
//notifyItemRangeRemoved(0, finallist.size());
//notifyDataSetChanged();
aux = aux - 1;
}
/*for (int i = 0; i< finallist.size(); i++){
if (finallist.get(i).size() > 1) {
System.out.println("groupImage: " + finallist.get(i).size());
} else {
System.out.println(finallist.get(i).get(0).getFeedType());
}
}*/
//returnList(finallist);
notifyItemRangeRemoved(0, returnList(finallist).size() - finallist.size() - 1);
//notifyItemRangeInserted(0, finallist.size());
}
public List<Feed> returnList(List<List<Feed>> lists) {
List<Feed> list = new ArrayList<>();
if (lists != null) {
for (int i = 0; i < lists.size(); i++) {
if (lists.get(i).size() > 1) {
for (int j = 0; j < lists.get(i).size(); j++) {
list.add(lists.get(i).get(j));
}
} else {
list.add(lists.get(i).get(0));
}
}
System.out.println("Tamanho de list: " + list.size());
}
return list;
}
}
And this is my Activity:
public abstract class FeedActivity extends UltraBaseActivity implements FeedAdapter.FeedItemListener, AudioManager.OnAudioFocusChangeListener, MediaPlayer.OnErrorListener, MediaPlayer.OnCompletionListener {
private static final String EXTRA_PROJECT_ID = "extra_project_id";
private static final String EXTRA_PROJECT_NAME = "extra_project_name";
private static final String EXTRA_RESOURCE_ID = "extra_resource_id";
private static final String EXTRA_RESOURCE_NAME = "extra_resource_name";
private static final String EXTRA_RESOURCE_KIND = "extra_resource_kind";
#BindView(R.id.swipeLayout) SwipeRefreshLayout mRefreshLayout;
#BindView(R.id.recyclerView) RecyclerView mRecyclerView;
#BindView(R.id.feedCreateFragment) View mFeedCreateLayout;
#BindView(R.id.mic) ImageView mMicView;
private WeakReference<FeedCreateFragment> mFeedCreateFragment;
protected FeedViewModel mViewModel;
protected FeedAdapter mAdapter;
private Feed mLongClick;
private Toolbar mToolbar;
protected int mScrollTo = -1;
protected WrapContentLinearLayoutManager mLayoutManager;
private String mPlayingFeedId;
private int mPlayingPos;
private int mActionResourcePause = R.drawable.ic_pause_black_24dp;
private int mActionResourcePlay = R.drawable.ic_play_black_24dp;
private MediaPlayer mPlayer;
private AudioManager mAudioManager;
protected Handler mAudioHandler;
protected Runnable mUpdateAudioHolderRunnable = new Runnable() {
#Override
public void run() {
try {
if (mPlayer != null && mPlayer.isPlaying()) {
notifyAdapterAudioUpdate(mPlayer.getCurrentPosition(), mActionResourcePause);
mAudioHandler.postDelayed(this, 100);
} else {
mAudioHandler.removeCallbacks(mUpdateAudioHolderRunnable);
}
} catch (IllegalStateException e){
MyLog.e(TAG, "Error while updating seed bar", e);
mAudioHandler.removeCallbacks(mUpdateAudioHolderRunnable);
}
}
};
public static void start(#NonNull Context context, #NonNull String projectId, #NonNull String projectName, #NonNull String resourceId, #NonNull String resourceName, #NonNull String resourceKind){
Intent intent = setIntent(context, projectId, projectName, resourceId, resourceName, resourceKind);
if (intent == null) return;
context.startActivity(intent);
}
public static void startForResult(#NonNull Fragment fragment, #NonNull String projectId, #NonNull String projectName, #NonNull String resourceId, #NonNull String resourceName, #NonNull String resourceKind){
Intent intent = setIntent(fragment.getContext(), projectId, projectName, resourceId, resourceName, resourceKind);
if (intent == null) return;
fragment.startActivityForResult(intent, Constants.Intents.INTENT_REQUEST_VIEW_FEED);
}
#Nullable
protected static Intent setIntent(#NonNull Context context, #NonNull String projectId, #NonNull String projectName, #NonNull String resourceId, #NonNull String resourceName, #NonNull String resourceKind) {
Intent intent;
if (resourceKind.equals(Task.ROUTE)) {
intent = new Intent(context, FeedTaskActivity.class);
}else if(resourceKind.equals(Chat.ROUTE)){
intent = new Intent(context, FeedChatActivity.class);
} else {
MyLog.e(TAG, "Error invalid resource Kind - " + resourceKind);
return null;
}
intent.putExtra(EXTRA_PROJECT_ID, projectId);
intent.putExtra(EXTRA_PROJECT_NAME, projectName);
intent.putExtra(EXTRA_RESOURCE_ID, resourceId);
intent.putExtra(EXTRA_RESOURCE_NAME, resourceName);
intent.putExtra(EXTRA_RESOURCE_KIND, resourceKind);
return intent;
}
public FeedActivity() {
super(R.layout.activity_feed);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
isLogged();
init(getIntent(), savedInstanceState);
super.onCreate(savedInstanceState);
initAdapter();
mAudioManager = (AudioManager) getSystemService(AUDIO_SERVICE);
mAudioHandler = new Handler();
mViewModel.subscribe()
.compose(this.<Resource<List<Feed>>>bindUntilEvent(ActivityEvent.DESTROY))
.flatMap(flatMapDiffUtils())
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(onNext(), onError(), onCompleted());
}
#NonNull
private Func1<Resource<List<Feed>>, Observable<FeedViewModel.Pipe>> flatMapDiffUtils() {
return new Func1<Resource<List<Feed>>, Observable<FeedViewModel.Pipe>>() {
#Override
public Observable<FeedViewModel.Pipe> call(Resource<List<Feed>> r) {
if (mViewModel.hasResource()) {
List<Feed> old = mAdapter.getItems();
MyLog.i(TAG, "New length: " + (r.data != null ? r.data.size() : 0) + " - Old: " + old.size());
final FeedDiffCallback cb = new FeedDiffCallback(old, r.data, mUser.getId());
final DiffUtil.DiffResult result = DiffUtil.calculateDiff(cb);
return Observable.just(new FeedViewModel.Pipe(r.data, result, r.status == Status.LOADING && (r.data ==null || r.data.size() == 0)));
} else {
MyLog.i(TAG, "Loading resource from server");
return Observable.empty();
}
}
};
}
private Action1<? super FeedViewModel.Pipe> onNext() {
return new Action1<FeedViewModel.Pipe>() {
#Override
public void call(FeedViewModel.Pipe pipe) {
if (pipe != null) {
initFeedFragment();
mRefreshLayout.setRefreshing(false);
pipe.mDiffResult.dispatchUpdatesTo(mAdapter);
mAdapter.setSkeletonMode(pipe.mSkeletonMode);
//List<List<Feed>> list = new ArrayList<>();
//list = tranformList(pipe.mList);
mAdapter.swap(transformList(pipe.mList));
System.out.println("Tamanho desse troço: " + transformList(pipe.mList).size());
//mAdapter.notifyDataSetChanged();
//mAdapter.notifyItemRangeRemoved(0, pipe.mList.size());
if (mScrollTo == -1) {
mRecyclerView.scrollToPosition(mAdapter.getItemCount()-1);
}else {
mRecyclerView.scrollToPosition(mScrollTo);
}
updateMenuOptions();
showLoading(false);
}
}
};
}
protected Action0 onCompleted() {
return new Action0() {
#Override
public void call() {
MyLog.i(TAG, "Finishing feed activity");
finish();
}
};
}
protected Action1<Throwable> onError() {
return new Action1<Throwable>() {
#Override
public void call(Throwable throwable) {
MyLog.e(TAG, "Error", throwable);
}
};
}
#Override
protected void initToolbar() {
mToolbar = (Toolbar) findViewById(R.id.toolbar);
if(mToolbar !=null) {
if (mViewModel != null) {
mToolbar.setTitle(mViewModel.getProjectName());
mToolbar.setSubtitle(mViewModel.getResourceName());
}
mToolbar.setSubtitleTextColor(ContextCompat.getColor(this, R.color.palette_black));
mToolbar.setNavigationIcon(R.drawable.ic_action_back_black);
}
setSupportActionBar(mToolbar);
if (mToolbar != null) {
mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onBackPressed();
}
});
}
}
protected void updateTitle(){
if(mToolbar !=null && mViewModel != null) {
mToolbar.setTitle(mViewModel.getProjectName());
mToolbar.setSubtitle(mViewModel.getResourceName());
}
}
#Override
protected void userUpdated(User user) { }
private void init(Intent i, Bundle b){
if (i != null) {
initViewModel(
i.getStringExtra(EXTRA_PROJECT_ID),
i.getStringExtra(EXTRA_PROJECT_NAME),
i.getStringExtra(EXTRA_RESOURCE_ID),
i.getStringExtra(EXTRA_RESOURCE_NAME),
i.getStringExtra(EXTRA_RESOURCE_KIND));
}else if(b != null){
initViewModel(
b.getString(EXTRA_PROJECT_ID),
b.getString(EXTRA_PROJECT_NAME),
b.getString(EXTRA_RESOURCE_ID),
b.getString(EXTRA_RESOURCE_NAME),
b.getString(EXTRA_RESOURCE_KIND));
}else {
MyLog.i(TAG, "Error while initializing view model");
finish();
}
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString(EXTRA_PROJECT_ID, mViewModel.getProjectId());
outState.putString(EXTRA_PROJECT_NAME, mViewModel.getProjectName());
outState.putString(EXTRA_RESOURCE_ID, mViewModel.getResourceId());
outState.putString(EXTRA_RESOURCE_NAME, mViewModel.getResourceName());
outState.putString(EXTRA_RESOURCE_KIND, mViewModel.getResourceKind());
}
private void initAdapter(){
mAdapter = new FeedAdapter(
this,
mUser.getId(),
getResources().getDimensionPixelSize(R.dimen.task_avatar_size),
(int) (AndroidUtils.getScreenWidth(this) * 0.6),
ContextCompat.getColor(this, R.color.bg_skeleton)
);
mRefreshLayout.setColorSchemeResources(R.color.yellow, android.R.color.darker_gray, R.color.yellow_edit_note, android.R.color.background_dark);
mRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
mScrollTo = -1;
mViewModel.reload();
}
});
mLayoutManager = new WrapContentLinearLayoutManager(this);
mRecyclerView.setLayoutManager(mLayoutManager);
mRecyclerView.setAdapter(mAdapter);
}
private void initFeedFragment(){
if(!(mFeedCreateFragment != null && mFeedCreateFragment.get() != null && getSupportFragmentManager().findFragmentById(R.id.feedCreateFragment) instanceof FeedCreateFragment)){
mFeedCreateFragment = new WeakReference<>(FeedCreateFragment.newInstance(mViewModel.getProjectId(), mViewModel.getResourceId(), mViewModel.getResourceKind(), mViewModel.getResourceUsers()));
getSupportFragmentManager()
.beginTransaction()
.add(R.id.feedCreateFragment, mFeedCreateFragment.get())
.commitAllowingStateLoss();
if (mViewModel.canCreateFeed()) {
mFeedCreateLayout.setVisibility(View.VISIBLE);
}else {
mFeedCreateLayout.setVisibility(View.GONE);
}
}
}
protected abstract void initViewModel(String projectId, String projectName, String resourceId, String resourceName, String resourceKind);
protected abstract void updateMenuOptions();
}
This is part of the Error (the text reached the maximum size):
10-18 17:29:14.702 23722-23722/com.construct.test E/WrapContentLinearLayoutManager: IndexOutOfBoundsException in RecyclerView happens
java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid view holder adapter positionViewHolder{615b449 position=3 id=-1, oldPos=0, pLpos:0 scrap [attachedScrap] tmpDetached no parent}
at android.support.v7.widget.RecyclerView$Recycler.validateViewHolderForOffsetPosition(RecyclerView.java:5297)
at android.support.v7.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:5479)
at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5440)
at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5436)
at android.support.v7.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:2224)
at android.support.v7.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1551)
at android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1511)
at android.support.v7.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:595)
at com.construct.v2.adapters.WrapContentLinearLayoutManager.onLayoutChildren(WrapContentLinearLayoutManager.java:20)

My problem was caused by the BaseSkeletonAdapter<Feed> that my FeedAdapter was extending. BaseSkeletonAdapter was using the original list and not the List of Lists I had to use. So I created a new class SkeletonAdapterFeed that is basically equal to the previous one, but the new one is receiving a List of Lists instead of just the List.
I know that it sounds a little confusing. I don't have full understanding of the project I am working right now so that's why I don't know everything about the classes, etc.

Related

How to generate pdf file and give command to print that generated file in android

i need to generate a pdf file and give print that file how do i do it in android i used the dependency
implementation 'org.apache.pdfbox:pdfbox:2.0.0-RC3'
and i code pdf Adapter as follows
public class PdfCreateAdapter extends RecyclerView.Adapter<PdfCreateAdapter.MyViewHolder> {
private List<PDFModel> pdfModels;
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_pdf_creation, parent, false);
return new MyViewHolder(itemView);
}
#Override
public void onBindViewHolder(MyViewHolder holder, int position) {
PDFModel model = pdfModels.get(position);
if (model != null) {
if (model.isReceived()) {
holder.mReceivedTV.setVisibility(View.VISIBLE);
} else {
holder.mReceivedTV.setVisibility(View.GONE);
}
holder.mPriceTV.setText(model.getPrice());
holder.mNameTV.setText(model.getName());
int ratingDrawable = getRatingImage(model.getRating());
holder.mRateIM.setImageResource(ratingDrawable);
}
}
#Override
public int getItemCount() {
return pdfModels.size();
}
/**
* This is set from PDFCreateByXML class
* This is my own model. This model have to set data from api
*
* #param pdfModels
*/
public void setListData(List<PDFModel> pdfModels) {
this.pdfModels = pdfModels;
notifyDataSetChanged();
}
/**
* Set rating image
*
* #param rating this is getting from api and set to image by rate point
* #return
*/
private int getRatingImage(float rating) {
int image = 0;
if (rating == 0f) {
image = R.drawable.pdf_star_1;
} else if (rating == 0.5f) {
image = R.drawable.pdf_half_star_2;
} else if (rating == 1f) {
image = R.drawable.pdf_star_2;
} else if (rating == 1.5f) {
image = R.drawable.pdf_half_star_3;
} else if (rating == 2f) {
image = R.drawable.pdf_star_3;
} else if (rating == 2.5f) {
image = R.drawable.pdf_half_star_4;
} else if (rating == 3f) {
image = R.drawable.pdf_star_4;
} else if (rating == 3.5f) {
image = R.drawable.pdf_half_star_5;
} else if (rating == 4f) {
image = R.drawable.pdf_star_5;
} else if (rating == 4.5f) {
image = R.drawable.pdf_half_star_6;
} else if (rating == 5f) {
image = R.drawable.pdf_star_6;
}
return image;
}
public class MyViewHolder extends RecyclerView.ViewHolder {
private final TextView mReceivedTV;
private final TextView mNameTV;
private final ImageView mRateIM;
private final TextView mPriceTV;
public MyViewHolder(View view) {
super(view);
mPriceTV = (TextView) view.findViewById(R.id.tv_price);
mReceivedTV = (TextView) view.findViewById(R.id.tv_received);
mNameTV = (TextView) view.findViewById(R.id.tv_name);
mRateIM = (ImageView) view.findViewById(R.id.iv_rate);
}
}
}
My pdf model that gets the data from xml
public class PDFModel {
private boolean isPending;
private boolean isReceived;
private String price;
private String name;
private float rating;
public boolean isPending() {
return isPending;
}
public void setPending(boolean pending) {
isPending = pending;
}
public boolean isReceived() {
return isReceived;
}
public void setReceived(boolean received) {
isReceived = received;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public float getRating() {
return rating;
}
public void setRating(float rating) {
this.rating = rating;
}
public String getPrice() {
return price;
}
public void setPrice(String price) {
this.price = price;
}
/**
* Create dummy PDF model
*
* #return PDF Models
*/
public static List<PDFModel> createDummyPdfModel() {
PDFCreationUtils.filePath.clear();
PDFCreationUtils.progressCount = 1;
boolean isFirstReceivedItem = false;
List<PDFModel> pdfModels = new ArrayList<>();
for (int i = 0; i < 110; i++) {
Random rand = new Random();
int price = rand.nextInt((1000 - 200) + 1) + 200;
PDFModel model = new PDFModel();
if (!isFirstReceivedItem) {
model.setReceived(true);
isFirstReceivedItem = true;
} else {
model.setReceived(false);
}
model.setPrice(String.valueOf(price) + String.valueOf(".0 Rs."));
if (i % 4 == 0) {
model.setName("Umesh Kumar " + i);
} else {
model.setName("Ram Kumar " + i);
}
model.setRating(i % 3);
pdfModels.add(model);
}
return pdfModels;
}
}
The flowing code is for crate pdf
this is pdfcrattionacivity.java
public class PdfCreationActivity extends AppCompatActivity {
private boolean IS_MANY_PDF_FILE;
/**
* This is identify to number of pdf file. If pdf model list size > sector so we have create many file. After that we have merge all pdf file into one pdf file
*/
private int SECTOR = 100; // Default value for one pdf file.
private int START;
private int END = SECTOR;
private int NO_OF_PDF_FILE = 1;
private int NO_OF_FILE;
private int LIST_SIZE;
private ProgressDialog progressDialog;
/**
* Store all dummy PDF models
*/
private List<PDFModel> pdfModels;
private TextView btnPdfPath;
/**
* Share PDF file
*/
private Button btnSharePdfFile;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_pdf_creation);
btnSharePdfFile = (Button) findViewById(R.id.btn_share_pdf);
btnPdfPath = (TextView) findViewById(R.id.btn_pdf_path);
findViewById(R.id.btn_create_pdf).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
requestPermission();
}
});
pdfModels = PDFModel.createDummyPdfModel();
RecyclerView rvShowDemo = (RecyclerView) findViewById(R.id.rv_show_demo);
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(this);
rvShowDemo.setLayoutManager(mLayoutManager);
PdfCreateAdapter pdfRootAdapter = new PdfCreateAdapter();
pdfRootAdapter.setListData(pdfModels);
rvShowDemo.setAdapter(pdfRootAdapter);
}
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
if (requestCode == 111 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
generatePdfReport();
}
}
private void requestPermission() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE}, 111);
} else {
generatePdfReport();
}
}
/**
* This is manage to all model
*/
private void generatePdfReport() {
// NO_OF_FILE : This is identify to one file or many file have to created
LIST_SIZE = pdfModels.size();
NO_OF_FILE = LIST_SIZE / SECTOR;
if (LIST_SIZE % SECTOR != 0) {
NO_OF_FILE++;
}
if (LIST_SIZE > SECTOR) {
IS_MANY_PDF_FILE = true;
} else {
END = LIST_SIZE;
}
createPDFFile();
}
private void createProgressBarForPDFCreation(int maxProgress) {
progressDialog = new ProgressDialog(this);
progressDialog.setMessage(String.format(getString(R.string.msg_progress_pdf), String.valueOf(maxProgress)));
progressDialog.setCancelable(false);
progressDialog.setIndeterminate(false);
progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progressDialog.setMax(maxProgress);
progressDialog.show();
}
private void createProgressBarForMergePDF() {
progressDialog = new ProgressDialog(this);
progressDialog.setMessage(getString(R.string.msg_progress_merger_pdf));
progressDialog.setCancelable(false);
progressDialog.show();
}
/**
* This function call with recursion
* This recursion depend on number of file (NO_OF_PDF_FILE)
*/
private void createPDFFile() {
// Find sub list for per pdf file data
List<PDFModel> pdfDataList = pdfModels.subList(START, END);
PdfBitmapCache.clearMemory();
PdfBitmapCache.initBitmapCache(getApplicationContext());
final PDFCreationUtils pdfCreationUtils = new PDFCreationUtils(PdfCreationActivity.this, pdfDataList, LIST_SIZE, NO_OF_PDF_FILE);
if (NO_OF_PDF_FILE == 1) {
createProgressBarForPDFCreation(PDFCreationUtils.TOTAL_PROGRESS_BAR);
}
pdfCreationUtils.createPDF(new PDFCreationUtils.PDFCallback() {
#Override
public void onProgress(final int i) {
progressDialog.setProgress(i);
}
#Override
public void onCreateEveryPdfFile() {
// Execute may pdf files and this is depend on NO_OF_FILE
if (IS_MANY_PDF_FILE) {
NO_OF_PDF_FILE++;
if (NO_OF_FILE == NO_OF_PDF_FILE - 1) {
progressDialog.dismiss();
createProgressBarForMergePDF();
pdfCreationUtils.downloadAndCombinePDFs();
} else {
// This is identify to manage sub list of current pdf model list data with START and END
START = END;
if (LIST_SIZE % SECTOR != 0) {
if (NO_OF_FILE == NO_OF_PDF_FILE) {
END = (START - SECTOR) + LIST_SIZE % SECTOR;
}
}
END = SECTOR + END;
createPDFFile();
}
} else {
// Merge one pdf file when all file is downloaded
progressDialog.dismiss();
createProgressBarForMergePDF();
pdfCreationUtils.downloadAndCombinePDFs();
}
}
#Override
public void onComplete(final String filePath) {
progressDialog.dismiss();
if (filePath != null) {
btnPdfPath.setVisibility(View.VISIBLE);
btnPdfPath.setText("PDF path : " + filePath);
Toast.makeText(PdfCreationActivity.this, "pdf file " + filePath, Toast.LENGTH_LONG).show();
btnSharePdfFile.setVisibility(View.VISIBLE);
btnSharePdfFile.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
sharePdf(filePath);
}
});
}
}
#Override
public void onError(Exception e) {
Toast.makeText(PdfCreationActivity.this, "Error " + e.getMessage(), Toast.LENGTH_LONG).show();
}
});
}
private void sharePdf(String fileName) {
final Intent emailIntent = new Intent(Intent.ACTION_SEND_MULTIPLE);
emailIntent.setType("text/plain");
emailIntent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
ArrayList<Uri> uris = new ArrayList<Uri>();
File fileIn = new File(fileName);
Uri u = FileProvider.getUriForFile(this, BuildConfig.APPLICATION_ID, fileIn);
uris.add(u);
emailIntent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uris);
try {
startActivity(Intent.createChooser(emailIntent, getString(R.string.send_to)));
} catch (ActivityNotFoundException e) {
Toast.makeText(this, getString(R.string.error_file), Toast.LENGTH_SHORT).show();
}
}
}
I am unable to get logic on how do i suppose to give command to print that generated PDF to printer
You'll need to connect to your printer and then send the PDDocument to the connected printer to print it. Something along the following lines should work.
public static PrintService choosePrinter() {
PrinterJob printJob = PrinterJob.getPrinterJob();
if(printJob.printDialog()) {
return printJob.getPrintService();
}
else {
return null;
}
}
public static void printPDF(String fileName, PrintService printer)
throws IOException, PrinterException {
PrinterJob job = PrinterJob.getPrinterJob();
job.setPrintService(printer);
PDDocument doc = PDDocument.load(fileName);
doc.silentPrint(job);
}
Code referenced from this SO answer.

how to track percentage of progressing download of each downloading file in exoplayer library?

I am working on a media player app. I'm using ExoPlayer library. I have a playlist of videos, and I want to download videos simultaneously. I done it by using available demo app of exoplayer library on GitHub. I want to show progress of each downloading in the UI. For this job I get help from DownloadNotificationUtil.buildProgressNotification method.
#Override
protected Notification getForegroundNotification(TaskState[] taskStates) {
float totalPercentage = 0;
int downloadTaskCount = 0;
boolean allDownloadPercentagesUnknown = true;
boolean haveDownloadedBytes = false;
boolean haveDownloadTasks = false;
boolean haveRemoveTasks = false;
Log.e(TAG,"size task state: "+taskStates.length);
for (TaskState taskState : taskStates) {
Log.e(TAG,"taskId= "+taskState.taskId);
if (taskState.state != TaskState.STATE_STARTED
&& taskState.state != TaskState.STATE_COMPLETED) {
continue;
}
if (taskState.action.isRemoveAction) {
haveRemoveTasks = true;
continue;
}
haveDownloadTasks = true;
if (taskState.downloadPercentage != C.PERCENTAGE_UNSET) {
allDownloadPercentagesUnknown = false;
totalPercentage += taskState.downloadPercentage;
}
haveDownloadedBytes |= taskState.downloadedBytes > 0;
downloadTaskCount++;
}
int progress = 0;
boolean indeterminate = true;
if (haveDownloadTasks) {
progress = (int) (totalPercentage / downloadTaskCount);
indeterminate = allDownloadPercentagesUnknown && haveDownloadedBytes;
Log.e(TAG,"notifi "+progress);
}
return DownloadNotificationUtil.buildProgressNotification(
this,
R.drawable.exo_icon_play,
DOWNLOAD_CHANNEL_ID,
null,
null,
taskStates);
}
Now,I can track the progress downloading. But I still have a problem. I can't understand which item is downloading to update it's progress bar in the UI. Is there a Identical id of each download to recognize it? For example Android Download Manager has a download ID for each downloading file. But I don't know , how to handle this problem.
This is MediaDownloadService:
public class MediaDownloadService extends DownloadService {
public static String TAG="MediaDownloadService";
private static final int FOREGROUND_NOTIFICATION_ID = 1;
public MediaDownloadService() {
super(
DOWNLOAD_NOTIFICATION_ID,
DEFAULT_FOREGROUND_NOTIFICATION_UPDATE_INTERVAL,
DOWNLOAD_CHANNEL_ID,
R.string.download_channel_name);
}
#Override
protected DownloadManager getDownloadManager() {
return ((MyApplication) getApplication()).getDownloadManager();
}
#Nullable
#Override
protected Scheduler getScheduler() {
return null;
}
#Override
protected Notification getForegroundNotification(TaskState[] taskStates) {
float totalPercentage = 0;
int downloadTaskCount = 0;
boolean allDownloadPercentagesUnknown = true;
boolean haveDownloadedBytes = false;
boolean haveDownloadTasks = false;
boolean haveRemoveTasks = false;
for (TaskState taskState : taskStates) {
if (taskState.state != TaskState.STATE_STARTED
&& taskState.state != TaskState.STATE_COMPLETED) {
continue;
}
if (taskState.action.isRemoveAction) {
haveRemoveTasks = true;
continue;
}
haveDownloadTasks = true;
if (taskState.downloadPercentage != C.PERCENTAGE_UNSET) {
allDownloadPercentagesUnknown = false;
totalPercentage += taskState.downloadPercentage;
}
haveDownloadedBytes |= taskState.downloadedBytes > 0;
downloadTaskCount++;
}
int progress = 0;
boolean indeterminate = true;
if (haveDownloadTasks) {
progress = (int) (totalPercentage / downloadTaskCount);
indeterminate = allDownloadPercentagesUnknown && haveDownloadedBytes;
Log.e(TAG,"notifi "+progress);
sendIntent(progress);
}
return DownloadNotificationUtil.buildProgressNotification(
this,
R.drawable.exo_icon_play,
DOWNLOAD_CHANNEL_ID,
null,
null,
taskStates);
}
private void sendIntent(int progress){
Intent intent = new Intent(ConstantUtil.MESSAGE_PROGRESS);
intent.putExtra("progress",progress);
LocalBroadcastManager.getInstance(MediaDownloadService.this).sendBroadcast(intent);
}
#Override
protected void onTaskStateChanged(TaskState taskState) {
if (taskState.action.isRemoveAction) {
return;
}
Notification notification = null;
if (taskState.state == TaskState.STATE_COMPLETED) {
Log.e(TAG,"STATE_COMPLETED");
notification =
DownloadNotificationUtil.buildDownloadCompletedNotification(
/* context= */ this,
R.drawable.exo_controls_play,
DOWNLOAD_CHANNEL_ID,
/* contentIntent= */ null,
Util.fromUtf8Bytes(taskState.action.data));
} else if (taskState.state == TaskState.STATE_FAILED) {
Log.e(TAG,"STATE_FAILED");
notification =
DownloadNotificationUtil.buildDownloadFailedNotification(
/* context= */ this,
R.drawable.exo_controls_play,
DOWNLOAD_CHANNEL_ID,
/* contentIntent= */ null,
Util.fromUtf8Bytes(taskState.action.data));
}
int notificationId = FOREGROUND_NOTIFICATION_ID + 1 + taskState.taskId;
NotificationUtil.setNotification(this, notificationId, notification);
}
}
This is DownloadTracker class:
public class DownloadTracker implements DownloadManager.Listener {
/** Listens for changes in the tracked downloads. */
public interface Listener {
/** Called when the tracked downloads changed. */
void onDownloadsChanged();
}
private static final String TAG = "DownloadTracker";
private final Context context;
private final DataSource.Factory dataSourceFactory;
private final TrackNameProvider trackNameProvider;
private final CopyOnWriteArraySet<Listener> listeners;
private Listener onDownloadsChanged;
private final HashMap<Uri, DownloadAction> trackedDownloadStates;
private final ActionFile actionFile;
private final Handler actionFileWriteHandler;
public DownloadTracker(
Context context,
DataSource.Factory dataSourceFactory,
File actionFile,
DownloadAction.Deserializer... deserializers) {
this.context = context.getApplicationContext();
this.dataSourceFactory = dataSourceFactory;
this.actionFile = new ActionFile(actionFile);
trackNameProvider = new DefaultTrackNameProvider(context.getResources());
listeners = new CopyOnWriteArraySet<>();
trackedDownloadStates = new HashMap<>();
HandlerThread actionFileWriteThread = new HandlerThread("DownloadTracker");
actionFileWriteThread.start();
actionFileWriteHandler = new Handler(actionFileWriteThread.getLooper());
loadTrackedActions(
deserializers.length > 0 ? deserializers : DownloadAction.getDefaultDeserializers());
}
public void addListener(Listener listener) {
listeners.add(listener);
}
public void removeListener(Listener listener) {
listeners.remove(listener);
}
public boolean isDownloaded(Uri uri) {
return trackedDownloadStates.containsKey(uri);
}
#SuppressWarnings("unchecked")
public List<StreamKey> getOfflineStreamKeys(Uri uri) {
if (!trackedDownloadStates.containsKey(uri)) {
return Collections.emptyList();
}
return trackedDownloadStates.get(uri).getKeys();
}
public int toggleDownload(Activity activity, String name, Uri uri, String extension) {
if (isDownloaded(uri)) {
Log.e(TAG,"isDownloaded");
DownloadAction removeAction =
getDownloadHelper(uri, extension).getRemoveAction(Util.getUtf8Bytes(name));
startServiceWithAction(removeAction);
return -1;
} else {
StartDownloadDialogHelper helper =
new StartDownloadDialogHelper(activity, getDownloadHelper(uri, extension), name);
helper.prepare();
return helper.getTaskId();
}
}
#Override
public void onInitialized(DownloadManager downloadManager) {
// Do nothing.
}
#Override
public void onTaskStateChanged(DownloadManager downloadManager, TaskState taskState) {
DownloadAction action = taskState.action;
Uri uri = action.uri;
if ((action.isRemoveAction && taskState.state == TaskState.STATE_COMPLETED)
|| (!action.isRemoveAction && taskState.state == TaskState.STATE_FAILED)) {
// A download has been removed, or has failed. Stop tracking it.
if (trackedDownloadStates.remove(uri) != null) {
handleTrackedDownloadStatesChanged();
}
}
}
#Override
public void onIdle(DownloadManager downloadManager) {
// Do nothing.
}
// Internal methods
private void loadTrackedActions(DownloadAction.Deserializer[] deserializers) {
try {
DownloadAction[] allActions = actionFile.load(deserializers);
for (DownloadAction action : allActions) {
trackedDownloadStates.put(action.uri, action);
}
} catch (IOException e) {
Log.e(TAG, "Failed to load tracked actions", e);
}
}
private void handleTrackedDownloadStatesChanged() {
for (Listener listener : listeners) {
listener.onDownloadsChanged();
}
final DownloadAction[] actions = trackedDownloadStates.values().toArray(new DownloadAction[0]);
Log.e(TAG,"actions: "+actions.toString());
actionFileWriteHandler.post(
() -> {
try {
actionFile.store(actions);
} catch (IOException e) {
Log.e(TAG, "Failed to store tracked actions", e);
}
});
}
private void startDownload(DownloadAction action) {
if (trackedDownloadStates.containsKey(action.uri)) {
// This content is already being downloaded. Do nothing.
Log.e(TAG,"download already exsit");
return;
}
trackedDownloadStates.put(action.uri, action);
handleTrackedDownloadStatesChanged();
startServiceWithAction(action);
}
private void startServiceWithAction(DownloadAction action) {
DownloadService.startWithAction(context, MediaDownloadService.class, action, false);
}
private DownloadHelper getDownloadHelper(Uri uri, String extension) {
int type = Util.inferContentType(uri, extension);
switch (type) {
case C.TYPE_DASH:
return new DashDownloadHelper(uri, dataSourceFactory);
case C.TYPE_SS:
return new SsDownloadHelper(uri, dataSourceFactory);
case C.TYPE_HLS:
return new HlsDownloadHelper(uri, dataSourceFactory);
case C.TYPE_OTHER:
return new ProgressiveDownloadHelper(uri);
default:
throw new IllegalStateException("Unsupported type: " + type);
}
}
private final class StartDownloadDialogHelper
implements DownloadHelper.Callback, DialogInterface.OnClickListener {
private final DownloadHelper downloadHelper;
private final String name;
private final AlertDialog.Builder builder;
private final View dialogView;
private final List<TrackKey> trackKeys;
private final ArrayAdapter<String> trackTitles;
private final ListView representationList;
private int taskId;
public StartDownloadDialogHelper(
Activity activity, DownloadHelper downloadHelper, String name) {
this.downloadHelper = downloadHelper;
this.name = name;
builder =
new AlertDialog.Builder(activity)
.setTitle(R.string.exo_download_description)
.setPositiveButton(android.R.string.ok, this)
.setNegativeButton(android.R.string.cancel, null);
// Inflate with the builder's context to ensure the correct style is used.
LayoutInflater dialogInflater = LayoutInflater.from(builder.getContext());
dialogView = dialogInflater.inflate(R.layout.start_download_dialog, null);
trackKeys = new ArrayList<>();
trackTitles =
new ArrayAdapter<>(
builder.getContext(), android.R.layout.simple_list_item_multiple_choice);
representationList = dialogView.findViewById(R.id.representation_list);
representationList.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
representationList.setAdapter(trackTitles);
}
public void prepare() {
downloadHelper.prepare(this);
}
#Override
public void onPrepared(DownloadHelper helper) {
for (int i = 0; i < downloadHelper.getPeriodCount(); i++) {
TrackGroupArray trackGroups = downloadHelper.getTrackGroups(i);
for (int j = 0; j < trackGroups.length; j++) {
TrackGroup trackGroup = trackGroups.get(j);
for (int k = 0; k < trackGroup.length; k++) {
trackKeys.add(new TrackKey(i, j, k));
trackTitles.add(trackNameProvider.getTrackName(trackGroup.getFormat(k)));
}
}
}
if (!trackKeys.isEmpty()) {
builder.setView(dialogView);
}
builder.create().show();
}
#Override
public void onPrepareError(DownloadHelper helper, IOException e) {
Toast.makeText(
context.getApplicationContext(), R.string.download_start_error, Toast.LENGTH_LONG)
.show();
Log.e(TAG, "Failed to start download", e);
}
#Override
public void onClick(DialogInterface dialog, int which) {
ArrayList<TrackKey> selectedTrackKeys = new ArrayList<>();
for (int i = 0; i < representationList.getChildCount(); i++) {
if (representationList.isItemChecked(i)) {
selectedTrackKeys.add(trackKeys.get(i));
}
}
if (!selectedTrackKeys.isEmpty() || trackKeys.isEmpty()) {
// We have selected keys, or we're dealing with single stream content.
DownloadAction downloadAction =
downloadHelper.getDownloadAction(Util.getUtf8Bytes(name), selectedTrackKeys);
taskId=MyApplication.getInstance().getDownloadManager().handleAction(downloadAction);
startDownload(downloadAction);
}
}
}
}
In my Fragment/Activity:
/* this method will be called when user click on download button of each item */
#Override
public void onDownloadClick(LectureList lecture) {
Log.e(TAG,"onClickDownload");
downloadTracker.toggleDownload(this,lecture.getTitle_lecture(),
Uri.parse(lecture.getUrlPath()),lecture.getExtension());
}
And here is my broadcast receiver:
private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Log.e(TAG,"onRecive download");
if(intent.getAction().equals(MESSAGE_PROGRESS)){
int progress=intent.getLongExtra("progress",0);
}
}
};
In the getForegroundNotification() method, you will get list of TaskState objects, which has a members downloadPercentage and your download Uri taskState.action.uri which is unique for each download task. Store these variables into a map and broadcast the map.
override fun getForegroundNotification(taskStates: Array<TaskState>): Notification {
var totalPercentage = 0f
var downloadTaskCount = 0
var progressMap : HashMap<Uri, Int> = HashMap()
for (taskState in taskStates) {
if (taskState.state != TaskState.STATE_STARTED && taskState.state != TaskState.STATE_COMPLETED) {
continue
}
if (taskState.action.isRemoveAction) {
continue
}
if (taskState.downloadPercentage != C.PERCENTAGE_UNSET.toFloat()) {
totalPercentage += taskState.downloadPercentage
progressMap.put(taskState.action.uri, taskState.downloadPercentage.toInt())
}
downloadTaskCount++
}
var progress = 0
progress = (totalPercentage / downloadTaskCount).toInt()
broadcastIndividualProgress(progressMap)
return buildProgressNotification(progress)
}

Recycler view swaps items when i scroll them

I am developing the chatbot app. I am using the RecycleView to render the chat of user and bot. I have to show the user listview or text response depend upon his query. All is working until my RecyclerView get's scroll. Whenever my RecyclerView gets scroll it changes the item position. I search a lot and applied every solution but not able to solve my issue.
here is my activity.java
public class HomeActivity extends AppCompatActivity implements AIListener,
View.OnClickListener {
private RecyclerView recyclerView;
private ChatAdapter mAdapter;
LinearLayoutManager layoutManager;
private ArrayList<Message> messageArrayList;
private EditText inputMessage;
private RelativeLayout btnSend;
Boolean flagFab = true;
PaytmPGService service = null;
Map<String, String> paytmparam = new HashMap<>();
PrefManager prefManager;
private AIService aiService;
AIDataService aiDataService;
AIRequest aiRequest;
Gson gson;
String food_dish = " ";
double price = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.RECORD_AUDIO}, 1);
inputMessage = findViewById(R.id.editText_ibm);
btnSend = findViewById(R.id.addBtnibm);
recyclerView = findViewById(R.id.recycler_view_ibm);
messageArrayList = new ArrayList<>();
mAdapter = new ChatAdapter(this,messageArrayList);
prefManager = new PrefManager(this);
GsonBuilder gsonBuilder = new GsonBuilder();
gson = gsonBuilder.create();
layoutManager = new LinearLayoutManager(this);
layoutManager.setStackFromEnd(true);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setHasFixedSize(true);
recyclerView.setItemAnimator(new DefaultItemAnimator());
mAdapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
#Override
public void onItemRangeInserted(int positionStart, int itemCount) {
super.onItemRangeInserted(positionStart, itemCount);
int msgCount = mAdapter.getItemCount();
int lastVisiblePosition = layoutManager.findLastCompletelyVisibleItemPosition();
if (lastVisiblePosition == -1 ||
(positionStart >= (msgCount - 1) &&
lastVisiblePosition == (positionStart - 1))) {
recyclerView.scrollToPosition(positionStart);
}
}
});
recyclerView.setAdapter(mAdapter);
this.inputMessage.setText("");
final AIConfiguration configuration = new AIConfiguration("cabc4b7b9c20409aa7ffb1b3d5fe1243",
AIConfiguration.SupportedLanguages.English,
AIConfiguration.RecognitionEngine.System);
aiService = AIService.getService(this, configuration);
aiService.setListener(this);
aiDataService = new AIDataService(configuration);
aiRequest = new AIRequest();
btnSend.setOnClickListener(this);
inputMessage.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
ImageView fab_img = findViewById(R.id.fab_img_ibm);
Bitmap img = BitmapFactory.decodeResource(getResources(), R.drawable.ic_send_white_24dp);
Bitmap img1 = BitmapFactory.decodeResource(getResources(), R.drawable.ic_mic_white_24dp);
if (s.toString().trim().length() != 0 && flagFab) {
ImageViewAnimatedChange(HomeActivity.this, fab_img, img);
flagFab = false;
} else if (s.toString().trim().length() == 0) {
ImageViewAnimatedChange(HomeActivity.this, fab_img, img1);
flagFab = true;
}
}
#Override
public void afterTextChanged(Editable s) {
}
});
}
public void ImageViewAnimatedChange(Context c, final ImageView v, final Bitmap new_image) {
final Animation anim_out = AnimationUtils.loadAnimation(c, R.anim.zoom_out);
final Animation anim_in = AnimationUtils.loadAnimation(c, R.anim.zoom_in);
anim_out.setAnimationListener(new Animation.AnimationListener()
{
#Override public void onAnimationStart(Animation animation) {}
#Override public void onAnimationRepeat(Animation animation) {}
#Override public void onAnimationEnd(Animation animation)
{
v.setImageBitmap(new_image);
anim_in.setAnimationListener(new Animation.AnimationListener() {
#Override public void onAnimationStart(Animation animation) {}
#Override public void onAnimationRepeat(Animation animation) {}
#Override public void onAnimationEnd(Animation animation) {}
});
v.startAnimation(anim_in);
}
});
v.startAnimation(anim_out);
}
#Override
public void onClick(View v) {
final String inputmessage = this.inputMessage.getText().toString().trim();
if(!inputmessage.equals("")){
new AsyncTask<String, Void, AIResponse>(){
private AIError aiError;
#Override
protected AIResponse doInBackground(final String... params) {
final AIRequest request = new AIRequest();
String query = params[0];
if (!TextUtils.isEmpty(query))
request.setQuery(query);
try {
return aiDataService.request(request);
} catch (final AIServiceException e) {
aiError = new AIError(e);
return null;
}
}
#Override
protected void onPostExecute(final AIResponse response) {
if (response != null) {
onResult(response);
} else {
onError(aiError);
}
}
}.execute(inputmessage);
}else {
aiService.startListening();
}
inputMessage.setText("");
}
#Override
public void onResult(AIResponse response) {
int itemNumber = 0;
Log.d("dialogeflow response",response.toString());
try {
JSONObject AIResponse = new JSONObject(gson.toJson(response));
Log.d("json response",AIResponse.toString());
final JSONObject result = AIResponse.getJSONObject("result");
JSONArray contexts = result.getJSONArray("contexts");
final JSONObject fulfillment = result.getJSONObject("fulfillment");
if(contexts.length()>0) {
for(int i = 0;i<contexts.length();i++) {
JSONObject context_items = contexts.getJSONObject(i);
JSONObject paramters = context_items.getJSONObject("parameters");
if (paramters.has("Cuisine")) {
prefManager.setCuisinetype(paramters.getString("Cuisine"));
} else if (paramters.has("Restaurants_name")) {
prefManager.setRestaurant_name(paramters.getString("Restaurants_name"));
}
if (paramters.has("number") && !paramters.getString("number").equals("") && paramters.has("Food_Dishes") && !paramters.getString("Food_Dishes").equals("")) {
itemNumber = Integer.parseInt(paramters.getString("number"));
if (itemNumber <= 2 && price !=0) {
price = 300 + (int) (Math.random() * ((1400 - 300) + 1));
} else {
price = 600 + (int) (Math.random() * ((2200 - 600) + 1));
}
food_dish = paramters.getString("Food_Dishes");
}
}
}
final double finalPrice = price;
final int finalItemNumber = itemNumber;
if(!result.getString("resolvedQuery").matches("payment is done successfully")) {
Message usermsg = new Message();
usermsg.setMessage(result.getString("resolvedQuery"));
usermsg.setId("1");
messageArrayList.add(usermsg);
mAdapter.notifyDataSetChanged();
if (fulfillment.has("speech")) {
Log.d("response of speech", fulfillment.getString("speech"));
if (!fulfillment.getString("speech").equals("") && fulfillment.getString("speech") != null) {
final String speech = fulfillment.getString("speech");
if (fulfillment.getString("speech").matches("Redirecting you to the Pay-Tm site")) {
new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
#Override
public void run() {
Message outMessage = new Message();
outMessage.setMessage(speech);
outMessage.setId("2");
messageArrayList.add(outMessage);
mAdapter.notifyDataSetChanged();
getpaytm_params((int) price);
}
}, 2000);
} else {
new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
#Override
public void run() {
Message outMessage = new Message();
if (speech.contains("Your total bill is ₹")) {
Log.d("price", String.valueOf(price));
outMessage.setMessage("Please Confirm your order:- \n" +finalItemNumber +" "+food_dish+" from "+prefManager.getRestaurant_name()+" at Flat No: 20,Galaxy Apartment,Airport Authority Colony,Andheri,Mumbai,Maharashtra 400 047 \n Your total bill is ₹"+price+". \n Do you want to pay by Wallet or by PayTm");
}else{
outMessage.setMessage(speech);
}
outMessage.setId("2");
messageArrayList.add(outMessage);
Log.d("messgae",outMessage.getMessage());
mAdapter.notifyDataSetChanged();
}
}, 2000);
}
} else {
final JSONArray msg = fulfillment.getJSONArray("messages");
for (int i = 0; i < msg.length(); i++) {
if (i == 0) {
Message outMessage = new Message();
JSONObject speechobj = msg.getJSONObject(i);
JSONArray speech = speechobj.getJSONArray("speech");
Log.d("response of speech", speech.getString(0));
outMessage.setMessage(speech.getString(0));
outMessage.setId("2");
messageArrayList.add(outMessage);
} else {
final int itemposition = i;
new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
#Override
public void run() {
Message outMessage = new Message();
try {
JSONObject speechobj = msg.getJSONObject(itemposition);
JSONArray speech = speechobj.getJSONArray("speech");
Log.d("response of speech", speech.getString(0));
outMessage.setMessage(speech.getString(0));
outMessage.setId("2");
messageArrayList.add(outMessage);
mAdapter.notifyDataSetChanged();
} catch (JSONException e) {
e.printStackTrace();
}
}
}, 5000);
}
}
}
}
}else{
if (!fulfillment.getString("speech").equals("") && fulfillment.getString("speech") != null) {
final String speech = fulfillment.getString("speech");
new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
#Override
public void run() {
Message outMessage = new Message();
outMessage.setMessage(speech);
outMessage.setId("2");
messageArrayList.add(outMessage);
mAdapter.notifyDataSetChanged();
}
},2000);
}
}
} catch (JSONException e) {
e.printStackTrace();
}
}
#Override
public void onError(AIError error) {
}
#Override
public void onAudioLevel(float level) {
}
#Override
public void onListeningStarted() {
btnSend.setBackground(getDrawable(R.drawable.recording_bg));
}
#Override
public void onListeningCanceled() {
btnSend.setBackground(getDrawable(R.drawable.stedy_recording));
}
#Override
public void onListeningFinished() {
btnSend.setBackground(getDrawable(R.drawable.stedy_recording));
}
}`
my ChatAdapter.java class
public class ChatAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private int BOT = 100;
private int BOT_Restaurant_ListView = 101;
private int USER = 102;
private Activity activity;
private PrefManager prefManager;
private int itemposition = -1;
private int menu_itemposition = -1;
private List<Restaurant_List_Model> restaurant_list;
private ArrayList<Message> messageArrayList;
private RestaurantListViewAdapter restaurantListViewAdapter;
private TextToSpeech tts ;
public ChatAdapter(Activity activity, ArrayList<Message> messageArrayList) {
this.activity = activity;
this.messageArrayList = messageArrayList;
tts = new TextToSpeech(activity, new TextToSpeech.OnInitListener() {
#Override
public void onInit(int status) {
if(status != TextToSpeech.ERROR){
tts.setLanguage(Locale.ENGLISH);
}
}
});
prefManager = new PrefManager(activity.getApplicationContext());
setHasStableIds(true);
}
#NonNull
#Override
public RecyclerView.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View itemview;
if(viewType == BOT){
itemview = LayoutInflater.from(parent.getContext()).inflate(R.layout.bot_msg_view,parent,false);
}else if(viewType == BOT_Restaurant_ListView){
itemview = LayoutInflater.from(parent.getContext()).inflate(R.layout.bot_msg_restaurant_listview,parent,false);
}else {
itemview = LayoutInflater.from(parent.getContext()).inflate(R.layout.user_msg_view,parent,false);
}
return new ViewHolder(itemview);
}
#Override
public int getItemViewType(int position) {
Message message = messageArrayList.get(position);
if(message.getId()!=null && message.getId().equals("2")){
if(message.getMessage().contains("restaurants") || message.getMessage().contains("restaurant")) {
return BOT_Restaurant_ListView;
}else {
return BOT;
}
}else{
return USER;
}
}
#Override
public void onBindViewHolder(#NonNull final RecyclerView.ViewHolder holder, int position) {
int pic_int = 1;
String filename = null;
final Message message = messageArrayList.get(position);
message.setMessage(message.getMessage());
if (holder.getItemViewType() == BOT_Restaurant_ListView) {
Log.d("inside bot listview msg", String.valueOf(BOT_Restaurant_ListView ));
Log.d("adapter position", String.valueOf(holder.getAdapterPosition()));
if(itemposition<holder.getAdapterPosition()){
itemposition = holder.getAdapterPosition();
Log.d("itemposition",String.valueOf(itemposition));
String jsonFileContent;
Log.d("cuisine value", prefManager.getCuisinetype());
if (message.getMessage().contains("restaurants")) {
if(!prefManager.getCuisinetype().equals("") && prefManager.getCuisinetype() != null){
Log.d("restauratn has drawn", "greate");
try {
restaurant_list = new ArrayList<>();
restaurantListViewAdapter = new RestaurantListViewAdapter(activity, restaurant_list);
((ViewHolder) holder).retaurant_listView.setVisibility(View.VISIBLE);
((ViewHolder) holder).retaurant_listView.setAdapter(restaurantListViewAdapter);
Log.d("cuisine value", prefManager.getCuisinetype());
if(message.getMessage().contains("Here are restaurants near you")){
String [] restaurant_Array ={
"indian","french","mexican","italian"
};
int randomNumber = (int) Math.floor(Math.random()*restaurant_Array.length);
filename = restaurant_Array[randomNumber];
Log.d("filename",filename);
jsonFileContent = readFile(activity.getResources().getIdentifier(filename, "raw", activity.getPackageName()));
}else {
filename = prefManager.getCuisinetype().toLowerCase() + "_restaurants";
Log.d("filename", filename);
jsonFileContent = readFile(activity.getResources().getIdentifier(filename, "raw", activity.getPackageName()));
}
JSONObject restaurantfile = new JSONObject(jsonFileContent);
JSONArray jsonArray = restaurantfile.getJSONArray("restaurants");
for (int i = 0; i < jsonArray.length(); i++) {
ImageRoundCorner imageRoundCorner = new ImageRoundCorner();
JSONObject restaurantList = jsonArray.getJSONObject(i);
Restaurant_List_Model restaurant_list_obj = new Restaurant_List_Model();
restaurant_list_obj.setName(restaurantList.getString("name"));
restaurant_list_obj.setLocation(restaurantList.getString("location"));
restaurant_list_obj.setImage_of_item(imageRoundCorner.getRoundedCornerBitmap(BitmapFactory.decodeResource(activity.getResources(), activity.getResources().getIdentifier("restaurant_" + pic_int, "drawable", activity.getPackageName()))));
pic_int++;
restaurant_list_obj.setRating(restaurantList.getLong("rating"));
restaurant_list.add(restaurant_list_obj);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
tts.speak(message.getMessage(), TextToSpeech.QUEUE_FLUSH, null, null);
} else {
tts.speak(message.getMessage(), TextToSpeech.QUEUE_FLUSH, null);
}
prefManager.setCuisinetype("");
pic_int = 1;
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
restaurantListViewAdapter.notifyDataSetChanged();
}
}else if(message.getMessage().contains("Here are some famous food items from "+prefManager.getRestaurant_name()+" restaurant")){
try {
Log.d("menu has draw","greate");
restaurant_list = new ArrayList<>();
restaurantListViewAdapter = new RestaurantListViewAdapter(activity, restaurant_list);
((ViewHolder) holder).retaurant_listView.setAdapter(restaurantListViewAdapter);
((ViewHolder) holder).retaurant_listView.setVisibility(View.VISIBLE);
Log.d("restaurant name value", prefManager.getRestaurant_name());
jsonFileContent = readFile(R.raw.restaurant_menu);
JSONObject menu_cuisine = new JSONObject(jsonFileContent);
ImageRoundCorner imageRoundCorner = new ImageRoundCorner();
if (menu_cuisine.has(prefManager.getRestaurant_name())) {
JSONObject restaurant_menu = menu_cuisine.getJSONObject("Dominos");
Log.d("Chili's American menu", restaurant_menu.toString());
JSONArray menu = restaurant_menu.getJSONArray("menu");
for (int j = 0; j < menu.length(); j++) {
JSONObject menu_obj = menu.getJSONObject(j);
Restaurant_List_Model restaurant_list_obj = new Restaurant_List_Model();
restaurant_list_obj.setName(menu_obj.getString("name"));
restaurant_list_obj.setLocation(menu_obj.getString("cuisine_type"));
restaurant_list_obj.setImage_of_item(imageRoundCorner.getRoundedCornerBitmap(BitmapFactory.decodeResource(activity.getResources(), activity.getResources().getIdentifier("menu_" + pic_int, "drawable", activity.getPackageName()))));
//restaurant_list_obj.setImage_of_item(imageRoundCorner.getRoundedCornerBitmap(BitmapFactory.decodeResource(activity.getResources(), activity.getResources().getIdentifier("menu_" + pic_int, "drawable", activity.getPackageName()))));
pic_int++;
restaurant_list_obj.setRating(menu_obj.getLong("rating"));
restaurant_list.add(restaurant_list_obj);
}
restaurantListViewAdapter.notifyDataSetChanged();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
tts.speak(message.getMessage(), TextToSpeech.QUEUE_FLUSH, null, null);
} else {
tts.speak(message.getMessage(), TextToSpeech.QUEUE_FLUSH, null);
}
pic_int = 1;
prefManager.setRestaurant_name("");
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
Log.d("user_message",message.getMessage());
tts.speak(message.getMessage(), TextToSpeech.QUEUE_FLUSH, null, null);
}else {
tts.speak(message.getMessage(), TextToSpeech.QUEUE_FLUSH, null);
}
pic_int = 1;
} catch (JSONException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
((ViewHolder) holder).retaurant_listView.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
int action = event.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
v.getParent().requestDisallowInterceptTouchEvent(true);
break;
case MotionEvent.ACTION_UP:
v.getParent().requestDisallowInterceptTouchEvent(false);
break;
}
v.onTouchEvent(event);
return true;
}
});
}
} if(holder.getItemViewType()==BOT) {
Log.d("adapter position", String.valueOf(holder.getAdapterPosition()));
Log.d("inside bot msg", String.valueOf(BOT));
((ViewHolder) holder).bot_msg.setText(message.getMessage());
if(itemposition<holder.getAdapterPosition()) {
itemposition = holder.getAdapterPosition();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
tts.speak(message.getMessage(), TextToSpeech.QUEUE_FLUSH, null, null);
} else {
tts.speak(message.getMessage(), TextToSpeech.QUEUE_FLUSH, null);
}
}
}if(holder.getItemViewType() == USER) {
((ViewHolder) holder).user_message.setText(message.getMessage());
}
}
#Override
public void onViewRecycled(#NonNull RecyclerView.ViewHolder holder) {
super.onViewRecycled(holder);
if(holder.isRecyclable()){
Log.d("inside onViewRecycled","great");
// itemposition = holder.getAdapterPosition();
}
}
#Override
public long getItemId(int position) {
return super.getItemId(position);
}
#Override
public int getItemCount() {
return messageArrayList.size();
}
private String readFile(int id) throws IOException
{
BufferedReader reader = null;
reader = new BufferedReader(new InputStreamReader(activity.getResources().openRawResource(id)));
String content = "";
String line;
while ((line = reader.readLine()) != null)
{
content = content + line;
}
return content;
}
public class ViewHolder extends RecyclerView.ViewHolder{
private TextView user_message,bot_msg;
private ListView retaurant_listView;
ViewHolder(View itemView) {
super(itemView);
bot_msg = itemView.findViewById(R.id.bot_message);
user_message = itemView.findViewById(R.id.message);
retaurant_listView = itemView.findViewById(R.id.restaurant_items_list_ibm);
}
}
}
Please help me out with this issue.
In gif, you can see the lower list is swap with the upper list and then return back

How to do Filter listview in android?

How to do the Filter concept from Below design? I here by attached two screen designs.
DashBoard Fragment -> Having Listview with Base adapter.
The above ListView code is given Below
DashBoardRefactor
public class DashBoardRefactor extends Fragment {
public static ProgressDialog progress;
public static List<DashListModel> dashRowList1 = new ArrayList<DashListModel>();
public static View footerView;
// #Bind(R.id.dashListView)
public static ListView dashListView;
int preCount = 2, scroll_Inc = 10, lastCount;
boolean flag = true;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.dashboard_fragment, container, false);
ButterKnife.bind(this, v);
setHasOptionsMenu(true);
progress = new ProgressDialog(getActivity());
dashListView = (ListView) v.findViewById(R.id.dashListView);
footerView = ((LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.dashboard_list_footer, null, false);
dashListView.addFooterView(footerView);
footerView.setVisibility(View.GONE);
dashRowList1.clear();
dashboardViewTask();
dashListView.setOnScrollListener(new EndlessScrollListener(getActivity(), dashListView, footerView));
return v;
}
public void dashboardViewTask() {
progress.setMessage("Loading...");
progress.setCanceledOnTouchOutside(false);
progress.setCancelable(false);
progress.show();
// footerView.setVisibility(View.VISIBLE);
Map<String, String> params = new HashMap<String, String>();
Log.e("candidate_id", "candidate_id---->" + SessionStores.getBullHornId(getActivity()));
params.put("candidate_id", SessionStores.getBullHornId(getActivity()));
params.put("employmentPreference", SessionStores.getEmploymentPreference(getActivity()));
params.put("page", "1");
new DashBoardTask(getActivity(), params, dashListView, footerView);
}
#Override
public void onCreateOptionsMenu(
Menu menu, MenuInflater inflater) {
if (menu != null) {
menu.removeItem(R.id.menu_notify);
}
inflater.inflate(R.menu.menu_options, menu);
MenuItem item = menu.findItem(R.id.menu_filter);
item.setVisible(true);
getActivity().invalidateOptionsMenu();
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle item selection
switch (item.getItemId()) {
case R.id.his__menu_accept:
Toast.makeText(getActivity(), "clicked dashboard menu accept", Toast.LENGTH_LONG).show();
return true;
case R.id.menu_filter:
// click evnt for filter
Toast.makeText(getActivity(), "clicked dashboard filter", Toast.LENGTH_LONG).show();
Intent filter_intent = new Intent(getActivity(), DashBoardFilterScreen.class);
startActivity(filter_intent);
getActivity().overridePendingTransition(R.anim.trans_left_in, R.anim.trans_left_out);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
public void onPause() {
super.onPause();
// dashboardViewTask();
}
}
DashBoardTask:
public class DashBoardTask {
public static String candidateIdNo;
public static Integer isBookmarked;
public ListAdapter dashListAdapter;
ListView dashListView;
View footerView;
String fromdate_formated = "";
String todate_formated = "";
private Context context;
private JSONObject jObject = null;
private String result, authorizationKey;
private Map<String, String> params;
public DashBoardTask(Context context, Map<String, String> params, ListView dashListView, View footerView) {
this.context = context;
Log.e("context ", "DashBoardTask: " + context);
this.dashListView = dashListView;
Dashboard.dashRowList.clear();
this.params = params;
this.footerView = footerView;
ResponseTask();
}
private void ResponseTask() {
authorizationKey = Constants.ACCESS_TOKEN;
new ServerResponse(ApiClass.getApiUrl(Constants.DASHBOARD_VIEW)).getJSONObjectfromURL(ServerResponse.RequestType.POST, params, authorizationKey, context, "", new VolleyResponseListener() {
#Override
public void onError(String message) {
if (DashBoardRefactor.progress.isShowing()) {
DashBoardRefactor.progress.dismiss();
}
}
#Override
public void onResponse(String response) {
String dateEnd = "", startDate = "";
result = response.toString();
try {
jObject = new JSONObject(result);
if (jObject != null) {
Integer totalJobList = jObject.getInt("page_count");
Integer total = jObject.getInt("total");
Integer count = jObject.getInt("count");
Integer start = jObject.getInt("start");
if (footerView.isShown() && count == 0) {
footerView.setVisibility(View.GONE);
}
Integer Status = jObject.getInt("status");
if (Status == 1) {
SessionStores.savetotalJobList(totalJobList, context);
JSONArray dataObject = jObject.getJSONArray("data");
Dashboard.dashRowList.clear();
for (int i = 0; i < dataObject.length(); i++) {
Log.e("length", "lenght----->" + dataObject.length());
JSONObject jobDetail = dataObject.getJSONObject(i);
Log.e("jobDetail", "jobDetail----->" + jobDetail);
Integer goalsName = jobDetail.getInt("id");
String compnyTitle = jobDetail.getString("title");
String description = jobDetail.getString("description");
Integer salary = jobDetail.getInt("salary");
String dateAdded = jobDetail.getString("dateAdded");
if (jobDetail.getString("startDate") != null && !jobDetail.getString("startDate").isEmpty() && !jobDetail.getString("startDate").equals("null")) {
startDate = jobDetail.getString("startDate");
} else {
Log.e("Task Null", "Task Null----startDate->");
}
if (jobDetail.getString("dateEnd") != null && !jobDetail.getString("dateEnd").isEmpty() && !jobDetail.getString("dateEnd").equals("null")) {
dateEnd = jobDetail.getString("dateEnd");
} else {
Log.e("Task Null", "Task Null----->");
}
isBookmarked = jobDetail.getInt("isBookmarked");
Integer startSalary = jobDetail.getInt("customFloat1");
Integer endSalary = jobDetail.getInt("customFloat2");
JSONObject cmpanyName = jobDetail.getJSONObject("clientCorporation");
String compnyNamede = cmpanyName.getString("name");
String city = jobDetail.getString("customText1");
JSONObject candidateId = jobDetail.getJSONObject("clientContact");
candidateIdNo = candidateId.getString("id");
DashListModel dashListItem = new DashListModel();
dashListItem.setDashCompanyName(compnyNamede);
dashListItem.setDashJobDescription(description);
dashListItem.setDashJobPosition(compnyTitle);
dashListItem.setDashJobCity(city);
// dashListItem.setDashJobState(state);
dashListItem.setDashSalary(startSalary.toString());
dashListItem.setDashJobAvailableDate(dateAdded);
dashListItem.setDashId(goalsName.toString());
dashListItem.setDashIsBookMarked(isBookmarked.toString());
dashListItem.setDashEndSalary(endSalary.toString());
dashListItem.setToDate(dateEnd);
////////////////////////////////////
String fromDate = null, toDate = null, postedDate = null;
if (startDate.length() > 11) {
Log.e("11", "11---->");
fromDate = Utils.convertFromUnixDateAdded(startDate);
} else if (startDate.length() == 10) {
Log.e("10", "10----->");
fromDate = Utils.convertFromUnix(startDate);
}
if (dateEnd.length() > 11) {
Log.e("11", "11---->");
toDate = Utils.convertFromUnixDateAdded(dateEnd);
} else if (dateEnd.length() == 10) {
Log.e("10", "10----->");
toDate = Utils.convertFromUnix(dateEnd);
}
if (dateAdded.length() > 11) {
Log.e("11", "11---->");
postedDate = Utils.convertFromUnixDateAdded(dateAdded);
} else if (dateAdded.length() == 10) {
Log.e("10", "10----->");
postedDate = Utils.convertFromUnix(dateAdded);
}
try {
if (!fromDate.isEmpty() || !fromDate.equalsIgnoreCase("null")) {
String[] fromDateSplit = fromDate.split("/");
String fromMonth = fromDateSplit[0];
String fromDat = fromDateSplit[1];
String fromYear = fromDateSplit[2];
String fromMonthName = new DateFormatSymbols().getMonths()[Integer.parseInt(fromMonth) - 1];
fromdate_formated = fromMonthName.substring(0, 3) + " " + fromDat + getDayOfMonthSuffix(Integer.parseInt(fromDat));
Log.e("fromdate", "fromdate---->" + fromDate);
Log.e("toDate", "toDate---->" + toDate);
Log.e("fromMonth", "fromMonth---->" + fromMonth);
Log.e("fromDat", "fromDat---->" + fromDat);
Log.e("fromYear", "fromYear---->" + fromYear);
}
if (!toDate.isEmpty() || !toDate.equalsIgnoreCase("null")) {
String[] toDateSplit = toDate.split("/");
String toMonth = toDateSplit[0];
String toDat = toDateSplit[1];
String toYear = toDateSplit[2];
String toMonthName = new DateFormatSymbols().getMonths()[Integer.parseInt(toMonth) - 1];
todate_formated = toMonthName.substring(0, 3) + " " + toDat + getDayOfMonthSuffix(Integer.parseInt(toDat)) + " " + toYear;
Log.e("________________", "-------------------->");
Log.e("toMonth", "toMonth---->" + toMonth);
Log.e("toDat", "toDat---->" + toDat);
Log.e("toYear", "toYear---->" + toYear);
Log.e("________________", "-------------------->");
Log.e("toMonthName", "toMonthName---->" + toMonthName);
}
} catch (Exception e) {
e.printStackTrace();
}
dashListItem.setPostedDate(postedDate);
dashListItem.setFromDate(fromdate_formated);
dashListItem.setEndDate(todate_formated);
/////////////////////////////////////////
// Dashboard.dashRowList.add(dashListItem);
DashBoardRefactor.dashRowList1.add(dashListItem);
}
// get listview current position - used to maintain scroll position
int currentPosition = dashListView.getFirstVisiblePosition();
dashListAdapter = new DashListAdapter(context, DashBoardRefactor.dashRowList1, dashListView);
dashListView.setAdapter(dashListAdapter);
((BaseAdapter) dashListAdapter).notifyDataSetChanged();
if (currentPosition != 0) {
// Setting new scroll position
dashListView.setSelectionFromTop(currentPosition + 1, 0);
}
} else if (Status==0 && count==0 && start==0){
String Message = jObject.getString("message");
Utils.ShowAlert(context, Message);
}
if (footerView.isShown()) {
footerView.setVisibility(View.GONE);
}
//progress.dismiss();
if (DashBoardRefactor.progress.isShowing()) {
try {
DashBoardRefactor.progress.dismiss();
} catch (Exception e) {
e.printStackTrace();
}
}
}
} catch (JSONException e) {
e.printStackTrace();
}
}
});
}
}
}
DashListModel:
public class DashListModel {
private String dashCompanyName;
private String dashJobPosition;
private String dashJobPostedDate;
private String dashJobDescription;
private String dashSalary;
private String dashJobCity;
private String dashJobState;
private String dashJobAvailableDate;
private String dashId, dashIsBookmarked;
private String dashEndSalary;
private String toDate;
private String postedDate, fromdate, enddate;
public String getDashCompanyName() {
return dashCompanyName;
}
public void setDashCompanyName(String dashCompanyName) {
this.dashCompanyName = dashCompanyName;
}
public String getDashJobPosition() {
return dashJobPosition;
}
public void setDashJobPosition(String dashJobPosition) {
this.dashJobPosition = dashJobPosition;
}
public String getDashJobDescription() {
return dashJobDescription;
}
public void setDashJobDescription(String dashJobDescription) {
this.dashJobDescription = dashJobDescription;
}
public String getDashJobPostedDate() {
return dashJobPostedDate;
}
public void setDashJobPostedDate(String dashJobPostedDate) {
this.dashJobPostedDate = dashJobPostedDate;
}
public String getDashSalary() {
return dashSalary;
}
public void setDashSalary(String dashSalary) {
this.dashSalary = dashSalary;
}
public String getDashJobCity() {
return dashJobCity;
}
public void setDashJobCity(String dashJobCity) {
this.dashJobCity = dashJobCity;
}
/* public String getDashJobState() {
return dashJobState;
}
public void setDashJobState(String dashJobState) {
this.dashJobState = dashJobState;
}*/
public String getDashJobAvailableDate() {
return dashJobAvailableDate;
}
public void setDashJobAvailableDate(String dashJobAvailableDate) {
this.dashJobAvailableDate = dashJobAvailableDate;
}
public String getDashId() {
return dashId;
}
public void setDashId(String dashId) {
this.dashId = dashId;
}
public String getDashIsBookmarked() {
return dashIsBookmarked;
}
public void setDashIsBookMarked(String dashIsBookmarked) {
this.dashIsBookmarked = dashIsBookmarked;
}
public String getDashEndSalary() {
return dashEndSalary;
}
public void setDashEndSalary(String dashEndSalary) {
this.dashEndSalary = dashEndSalary;
}
public String getToDate() {
return toDate;
}
public void setToDate(String toDate) {
this.toDate = toDate;
}
public String getPostedDate() {
return postedDate;
}
public void setPostedDate(String postedDate) {
this.postedDate = postedDate;
}
public String getFromDate() {
return fromdate;
}
public void setFromDate(String fromdate) {
this.fromdate = fromdate;
}
public String getEndDate() {
return enddate;
}
public void setEndDate(String enddate) {
this.enddate = enddate;
}
DashListAdapter:
package com.peoplecaddie.adapter;
public class DashListAdapter extends BaseAdapter {
public static ListView dashListView;
Context c;
private LayoutInflater inflater;
private List<DashListModel> dashRowList;
public DashListAdapter(Context c, List<DashListModel> dashRowList, ListView dashListView) {
this.c = c;
this.dashListView = dashListView;
this.dashRowList = dashRowList;
}
#Override
public int getCount() {
return this.dashRowList.size();
}
#Override
public Object getItem(int position) {
return dashRowList.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
final ViewHolder dashHolder;
if (inflater == null)
inflater = (LayoutInflater) c
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (convertView == null)
convertView = inflater.inflate(R.layout.dashboard_jobdetails_list, null);
final DashListModel dashModel = dashRowList.get(position);
dashHolder = new ViewHolder(convertView);
dashHolder.dash_company_name.setText(dashModel.getDashCompanyName());
dashHolder.dash_position_name.setText(dashModel.getDashJobPosition());
dashHolder.dash_posted_date.setText(dashModel.getPostedDate());
dashHolder.dash_job_description.setText(Utils.stripHtml(dashModel.getDashJobDescription()));
dashHolder.dash_salary.setText(dashModel.getDashSalary() + " - " + dashModel.getDashEndSalary());
dashHolder.dash_available_date.setText(dashModel.getFromDate() + " - " + dashModel.getEndDate());
dashHolder.book_jobCity.setText(dashModel.getDashJobCity());
if (dashModel.getDashIsBookmarked().equalsIgnoreCase("1")) {
dashHolder.bookmark_img.setImageResource(R.drawable.bookmark);
} else if (dashModel.getDashIsBookmarked().equalsIgnoreCase("0")) {
dashHolder.bookmark_img.setImageResource(R.drawable.blue_tag_img);
}
dashHolder.bookmark_img.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
if (dashModel.getDashIsBookmarked().equalsIgnoreCase("0")) {
dashModel.setDashIsBookMarked("1");
Map<String, String> params = new HashMap<String, String>();
params.put("candidate_id", SessionStores.getBullHornId(c));
params.put("joborder_id", dashModel.getDashId());
BackGroundTasks bookmark_add_bg_tasks = new BackGroundTasks(c, new JSONObject(params), Constants.BOOKMARK_ADD_TAG);
bookmark_add_bg_tasks.ResponseTask(new BackGroundTasks.VolleyCallbackOnEdit() {
#Override
public void onSuccess(String result) {
String resp_resultsd = result;
Log.e("insidecallback", " bookmark_add_bg_tasks----->" + resp_resultsd);
// finish();
dashHolder.bookmark_img.setImageResource(R.drawable.bookmark);
notifyDataSetChanged();
}
});
} else if (dashModel.getDashIsBookmarked().equalsIgnoreCase("1")) {
dashModel.setDashIsBookMarked("0");
Log.e("imgchange", " imgchange");
Map<String, String> params = new HashMap<String, String>();
params.put("candidate_id", SessionStores.getBullHornId(c));
params.put("joborder_id", dashModel.getDashId());
BackGroundTasks bookmark_delete_bg_tasks = new BackGroundTasks(c, new JSONObject(params), Constants.BOOKMARK_DELETE_TAG);
bookmark_delete_bg_tasks.ResponseTask(new BackGroundTasks.VolleyCallbackOnEdit() {
#Override
public void onSuccess(String result) {
String resp_resultsd = result;
Log.e("insidecallback", " bookmark_delete_bg_tasks----->" + resp_resultsd);
// finish();
dashHolder.bookmark_img.setImageResource(R.drawable.blue_tag_img);
notifyDataSetChanged();
}
});
}
}
});
return convertView;
}
static class ViewHolder {
#Bind(R.id.book_company_name)
TextView dash_company_name;
private RelativeLayout.LayoutParams viewLayParams;
public ViewHolder(View view) {
ButterKnife.bind(this, view);
}
}
}
Clarification:
How do to Filter while click the Filter Button On DashBoard Fragment. Please Suggest the way. I here by attached My Filter design also.
Dashboard Fragment--> Filter Button-> Filter screen-> the Filtered results should view on DashBoard Fragment.
Once click the apply Button Based on the input from Filter screen it filters the list view the result comes from back end team. I have to display that result on Dashboard Fragment.
Kindly please clarify this Filter concept.

notifyDataSetChanged does not update the listView of custom objects after sorting

I am trying to sort the collection in custom arrayadapter and making a call to update the view . However, the view does not gets updated.
There are two values over which I want to sort (date and amount) and have a custom comparators for them.
I can see that the data itself has changed (i.e if a list item has gone outside of view after sorting and when it gets the view, the data it show is the correct data that should exist after sorting).
The second question is about the filter. The way the filter is implemented right now, it does not update the views either.
Here is code
public class SearchActivity extends BListActivity {
private Bundle sessionInfo;
private TransactionDetailsHandler transactionDetailsHandler = new TransactionDetailsHandler();
private static boolean ascDate = false;
private static boolean ascAmount = false;
private ArrayList<TransactionDetails> transactionDetails;
private ArrayList<TransactionDetails> filterResults;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
sessionInfo = getIntent().getExtras();
final String sessionId = sessionInfo.getString("sessionId");
final String transactionResponse = sessionInfo
.getString(C.TRN_DETAIL_KEY);
try {
Xml.parse(transactionResponse, transactionDetailsHandler);
} catch (Exception ex) {
ex.printStackTrace();
}
final ArrayAdapter<TransactionDetails> adapter = getArrayAdapter();
findViewById(R.id.amount_btn).setOnClickListener(
new View.OnClickListener() {
public void onClick(View v) {
if (ascDate) {
adapter.sort(new TransactionDetailAmountComparatorAsc());
ascDate = false;
} else {
adapter.sort(new TransactionDetailAmountComparatorDesc());
ascDate = true;
}
adapter.notifyDataSetChanged();
}
});
findViewById(R.id.date_btn).setOnClickListener(
new View.OnClickListener() {
public void onClick(View v) {
if (ascAmount) {
adapter.sort(new TransactionDetailDateComparatorAsc());
ascAmount = false;
} else {
adapter.sort(new TransactionDetailDateComparatorDesc());
ascAmount = true;
}
adapter.notifyDataSetChanged();
}
});
findViewById(R.id.search_btn).setOnClickListener(
new View.OnClickListener() {
public void onClick(View v) {
findViewById(R.id.buttonLL).setVisibility(View.GONE);
findViewById(R.id.searchLL).setVisibility(View.VISIBLE);
}
});
findViewById(R.id.cancel_btn).setOnClickListener(
new View.OnClickListener() {
public void onClick(View v) {
findViewById(R.id.searchLL).setVisibility(View.GONE);
findViewById(R.id.buttonLL).setVisibility(View.VISIBLE);
}
});
TextWatcher filterTextWatcher = new TextWatcher() {
public void afterTextChanged(Editable s) {
}
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
public void onTextChanged(CharSequence s, int start, int before,
int count) {
System.out.println("XXXX Constraint = " + s);
adapter.getFilter().filter(s);
}
};
EditText et = (EditText) findViewById(R.id.edit_box);
et.addTextChangedListener(filterTextWatcher);
}
protected ArrayAdapter<TransactionDetails> getArrayAdapter() {
transactionDetails = transactionDetailsHandler
.getTransactionDetailsList();
filterResults = transactionDetails;
return new SearchListAdapter(this,
(List<TransactionDetails>) transactionDetails);
}
protected class SearchListAdapter extends ArrayAdapter<TransactionDetails> {
private int rId;
private List<TransactionDetails> data;
private Filter filter;
public SearchListAdapter(Context context, List<TransactionDetails> data) {
super(context, R.layout.search_list_item, data);
this.rId = R.layout.search_list_item;
this.data = data;
}
#Override
public View getView(int position, View cv, ViewGroup parent) {
cv = getLayoutInflater().inflate(rId, parent, false);
TransactionDetails item = data.get(position);
((TextView) cv.findViewById(R.id.t_id)).setText(item.getTrnId());
((TextView) cv.findViewById(R.id.date)).setText(item
.getTrnDatetime());
((TextView) cv.findViewById(R.id.amount)).setText(item
.getTrnAmount());
((TextView) cv.findViewById(R.id.card_num))
.setText("XXXX XXXX XXXX " + item.getTrnMaskedCard());
try {
if (item.getTrnCardType() != null
&& item.getTrnCardType().trim().length() > 0)
((ImageView) cv.findViewById(R.id.card_img))
.setImageResource(Integer.parseInt(item
.getTrnCardType()));
} catch (Exception ex) {
ex.printStackTrace();
}
((TextView) cv.findViewById(R.id.result)).setText(item
.getTrnStatus());
return cv;
}
#Override
public Filter getFilter() {
if (filter == null)
filter = new TransactionDetailFilter();
return filter;
}
private class TransactionDetailFilter extends Filter {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
System.out.println("XXXX Started filtering with Constraint = "
+ constraint);
FilterResults results = new FilterResults();
String prefix = constraint.toString().toLowerCase();
if (prefix == null || prefix.length() == 0) {
ArrayList<TransactionDetails> list = new ArrayList<TransactionDetails>(
transactionDetails);
results.values = list;
results.count = list.size();
} else {
final ArrayList<TransactionDetails> list = new ArrayList<TransactionDetails>(
transactionDetails);
final ArrayList<TransactionDetails> nlist = new ArrayList<TransactionDetails>();
int count = list.size();
System.out
.println("XXXX List to be search size = " + count);
for (int i = 0; i < count; i++) {
final TransactionDetails details = list.get(i);
System.out.println("XXXX List to be searched = "
+ details.toString());
if (details.getTrnId().startsWith(prefix)
|| details.getTrnDatetime().startsWith(prefix)
|| details.getTrnAmount().startsWith(prefix)
|| details.getTrnMaskedCard()
.startsWith(prefix)
|| details.getTrnStatus().startsWith(prefix)) {
System.out.println("XXXX Adding result "
+ details.toString());
nlist.add(details);
}
}
results.values = nlist;
results.count = nlist.size();
}
System.out.println("XXXX Ended filtering with Constraint = "
+ constraint + " . Result size = " + results.count);
return results;
}
#SuppressWarnings("unchecked")
#Override
protected void publishResults(CharSequence constraint,
FilterResults results) {
System.out.println("XXXX Preparing to publish results. Result size = "+ results.count);
ArrayList<TransactionDetails> fitems = (ArrayList<TransactionDetails>) results.values;
clear();
int count = fitems.size();
for (int i = 0; i < count; i++) {
TransactionDetails details = (TransactionDetails) fitems
.get(i);
add(details);
}
notifyDataSetChanged();
System.out.println("XXXX Finished publishing results.");
}
}
#Override
public void add(TransactionDetails item) {
System.out.println("XXXX Adding items to be published." + item.toString());
filterResults.add(item);
}
}
// -------------------------------------------------------------------------------------------------------------------------------------------------
class TransactionDetailAmountComparatorAsc implements
Comparator<TransactionDetails> {
public int compare(TransactionDetails detail1,
TransactionDetails detail2) {
float f = Float.parseFloat(detail1.getTrnAmount())
- Float.parseFloat(detail2.getTrnAmount());
if (f > 0)
return 1;
if (f < 1)
return -1;
return 0;
}
}
class TransactionDetailAmountComparatorDesc implements
Comparator<TransactionDetails> {
public int compare(TransactionDetails detail1,
TransactionDetails detail2) {
float f = Float.parseFloat(detail1.getTrnAmount())
- Float.parseFloat(detail2.getTrnAmount());
if (f > 0)
return -1;
if (f < 1)
return 1;
return 0;
}
}
class TransactionDetailDateComparatorAsc implements
Comparator<TransactionDetails> {
public int compare(TransactionDetails detail1,
TransactionDetails detail2) {
detail1.getTrnDatetime();
detail2.getTrnDatetime();
String pattern = "MM/dd/yy HH:mm";
SimpleDateFormat format = new SimpleDateFormat(pattern);
try {
Date date1 = format.parse(detail1.getTrnDatetime());
Date date2 = format.parse(detail2.getTrnDatetime());
return date1.compareTo(date2);
} catch (Exception e) {
e.printStackTrace();
}
return 0;
}
}
class TransactionDetailDateComparatorDesc implements
Comparator<TransactionDetails> {
public int compare(TransactionDetails detail1,
TransactionDetails detail2) {
detail1.getTrnDatetime();
detail2.getTrnDatetime();
String pattern = "MM/dd/yy HH:mm";
SimpleDateFormat format = new SimpleDateFormat(pattern);
try {
Date date1 = format.parse(detail1.getTrnDatetime());
Date date2 = format.parse(detail2.getTrnDatetime());
return -(date1.compareTo(date2));
} catch (Exception e) {
e.printStackTrace();
}
return 0;
}
}
#Override
public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
position -= ((ListView) parent).getHeaderViewsCount();
TransactionDetails details = (TransactionDetails) parent.getAdapter()
.getItem(position);
Bundle b = new Bundle(sessionInfo);
b.putSerializable(C.TRN_DETAIL_KEY, details);
Util.openView(SearchActivity.this, TransDetailActivity.class, b);
}
#Override
protected int getContentView() {
return R.layout.search_layout;
}
#Override
protected int getStringArrayID() {
return 0;
}
#Override
protected Class<?>[] getDestinations() {
return null;
}
#Override
protected int getTitleId() {
return R.string.search;
}
}

Categories

Resources