Problem with animation loading more items in recyclerview

0

I'm applying an animation in the display of items in my recyclerview, however, when I load more items, the last item in my recyclerview is animated again in a strange way.

Here are my code snippets related to recyclerview.

MainActivity.java

public class MainActivity extends BaseActivity implements RecyclerViewOnClickListenerHack {

    public static String IDENTIFIER = "MainActivity";

    private Locale myLocale;
    private List<Post> mList = null;
    private RecyclerView mRecyclerView;
    private PostAdapter mAdapter;

    private FrameLayout mProgress;
    private LinearLayout mSlowConnection;
    private LinearLayout mNotFound;

    private boolean mInRequest = false;
    private Integer mOffset = 0;
    private Integer mLimit = 50;

    private Button mBtnReload;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        toolbar.setTitle(getString(R.string.general));
        setSupportActionBar(toolbar);

        super.setDrawer(MainActivity.this, toolbar);

        mRecyclerView = (RecyclerView) findViewById(R.id.rvPostList);
        mRecyclerView.setHasFixedSize(true);

        final LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
        linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
        mRecyclerView.setLayoutManager(linearLayoutManager);
        mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);
                if(mList.size() == linearLayoutManager.findLastCompletelyVisibleItemPosition() + 1){
                    if(!mInRequest){
                        getMorePosts();
                    }
                }
            }
        });

        mProgress = (FrameLayout) findViewById(R.id.fl_progress);
        mSlowConnection = (LinearLayout) findViewById(R.id.ll_slow_connection);
        mNotFound = (LinearLayout) findViewById(R.id.ll_not_found);

        mBtnReload = (Button) findViewById(R.id.btn_reload);
        mBtnReload.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mProgress.setVisibility(View.VISIBLE);
                mSlowConnection.setVisibility(View.GONE);
                getPosts();
            }
        });

        getPosts();

        setImgProfile();

    }

    public void getPosts(){
        Call<List<Post>> call = mService.getPostsPaginated(MonitorSettings.ALL, mLimit, mOffset);
        call.enqueue(new Callback<List<Post>>() {
            @Override
            public void onResponse(Call<List<Post>> call, Response<List<Post>> response) {
                mProgress.setVisibility(View.GONE);
                mSlowConnection.setVisibility(View.GONE);

                if(response.isSuccessful()){
                    mList = response.body();
                    if(!mList.isEmpty()){
                        mOffset++;
                        mAdapter = new PostAdapter(MainActivity.this, mList);
                        mAdapter.setRecyclerViewOnClickListenerHack(MainActivity.this);
                        mRecyclerView.setAdapter(mAdapter);
                    }
                    else{
                        mNotFound.setVisibility(View.VISIBLE);
                    }
                }
                else{
                    AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
                    builder.setTitle(getString(R.string.oops));
                    builder.setMessage(getString(R.string.login_again));
                    builder.setCancelable(false);
                    builder.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            logout();
                        }
                    });
                    builder.show();
                }
            }

            @Override
            public void onFailure(Call<List<Post>> call, Throwable t) {
                mProgress.setVisibility(View.GONE);
                mSlowConnection.setVisibility(View.VISIBLE);
            }
        });
    }

    public void getMorePosts(){
        mInRequest = true;
        mAdapter.addProgressBar();
        mRecyclerView.scrollToPosition(mList.size() - 1);
        Call<List<Post>> call = mService.getPostsPaginated(MonitorSettings.ALL, mLimit, mOffset);
        call.enqueue(new Callback<List<Post>>() {
            @Override
            public void onResponse(Call<List<Post>> call, Response<List<Post>> response) {
                mAdapter.removeProgressBar();

                if(response.isSuccessful()){
                    if(!mList.isEmpty()){
                        mOffset++;
                        mInRequest = false;

                        List<Post> posts = response.body();
                        for(Post post : posts){
                            mAdapter.addListItem(post, mList.size());
                        }
                    }
                    else{
                        Snackbar.make(mRecyclerView, "Todas as publicações já foram carregadas", Snackbar.LENGTH_INDEFINITE)
                                .setAction("Ok", new View.OnClickListener() {
                                    @Override
                                    public void onClick(View v) {

                                    }
                                }).show();
                    }
                }
                else{
                    AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
                    builder.setTitle(getString(R.string.oops));
                    builder.setMessage(getString(R.string.login_again));
                    builder.setCancelable(false);
                    builder.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            logout();
                        }
                    });
                    builder.show();
                }
            }

            @Override
            public void onFailure(Call<List<Post>> call, Throwable t) {
                Snackbar.make(mRecyclerView, "Não foi possível carregar mais publicações. Tente novamente", Snackbar.LENGTH_INDEFINITE)
                        .setAction("Ok", new View.OnClickListener() {
                            @Override
                            public void onClick(View v) {
                                getMorePosts();
                            }
                        }).show();
            }
        });
    }

    public void setLocale(String lang) {
        myLocale = new Locale(lang);
        Resources res = getResources();
        DisplayMetrics dm = res.getDisplayMetrics();
        Configuration conf = res.getConfiguration();
        conf.locale = myLocale;
        res.updateConfiguration(conf, dm);
        Intent refresh = new Intent(this, MainActivity.class);
        refresh.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        startActivity(refresh);
    }

    @Override
    public void startActivity(Intent intent) {
        if(Intent.ACTION_SEARCH.equalsIgnoreCase(intent.getAction())){
            intent.putExtra("page", MonitorSettings.ALL);
        }
        super.startActivity(intent);
    }

    @Override
    public void onClickListener(View view, int position) {
        Intent intent = new Intent(MainActivity.this, PostDetailsActivity.class);
        intent.putExtra("title", mList.get(position).getStatus());
        intent.putExtra("page", MonitorSettings.ALL);
        intent.putExtra("postId", mList.get(position).getId());
        intent.putExtra("postType", mList.get(position).getPostType());
        startActivity(intent);
    }
}

PostAdapter.java

public class PostAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>{

    private Context mCtx;

    private LayoutInflater mLayoutInflater;
    private List<Post> mList;
    private RecyclerViewOnClickListenerHack mRecyclerViewOnClickListenerHack;

    private Integer mProgressPosition = -1;
    private Integer mLastPosition = -1;

    public PostAdapter(Context ctx, List<Post> postList){
        this.mCtx = ctx;
        mList = postList;
        mLayoutInflater = (LayoutInflater) ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        RecyclerView.ViewHolder mvh;
        if(viewType == 0) {
            View v = mLayoutInflater.inflate(R.layout.post_item_main, parent, false);
            mvh = new PostViewHolder(v);
        }else {
            View v = mLayoutInflater.inflate(R.layout.ll_progress_item, parent, false);
            mvh = new ProgressViewHolder(v);
        }
        return mvh;
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position) {
        if(viewHolder instanceof ProgressViewHolder) {
            ((ProgressViewHolder) viewHolder).progressBar.setIndeterminate(true);
        }
        else if(viewHolder instanceof PostViewHolder){
            PostViewHolder holder = ((PostViewHolder) viewHolder);
            holder.txtStatus.setText(mList.get(position).getStatus());
            holder.txtId.setText(String.format(mCtx.getString(R.string.post_id), mList.get(position).getId().toString()));
            try {
                holder.txtDate.setText(MonitorApplication.getConvertedDate(mList.get(position).getCreated_at(), MonitorSettings.SMALL_DATE_FORMAT, MonitorSettings.OUTPUT_DATE_FORMAT));
            } catch (ParseException e) {
                e.printStackTrace();
            }
            String name = mList.get(position).getAssignee();
            if (name != null && !name.isEmpty()) {
                holder.txtName.setText(mList.get(position).getAssignee());
            } else {
                holder.txtName.setText(mCtx.getString(R.string.user_unidentified));
            }
            if (mList.get(position).getAssignee() == null) {
//            holder.txtName.setVisibility(View.GONE);
                holder.txtName.setText(mCtx.getString(R.string.responsible_unidentified));
            }
            holder.txtSubject.setText(mList.get(position).getCategory());
            holder.txtLocale.setText(mList.get(position).getNeighborhood());

            setAnimation(holder.llContent, position);
        }
    }

    @Override
    public int getItemCount() {
        return mList.isEmpty() ? 0 : mList.size();
    }

    public void addListItem(Post post, int position){
        mList.add(post);
        notifyItemInserted(position);
    }

    public void addProgressBar(){
        mList.add(null);
        notifyItemInserted(mList.size());
        mProgressPosition = mList.size()-1;
    }

    public void removeProgressBar(){
        mList.remove(mList.size() - 1);
        notifyItemRemoved(mList.size() - 1);
        mProgressPosition = -1;
    }

    @Override
    public int getItemViewType(int position) {
        Log.d("Thiago", "position: " + position);
        Log.d("Thiago", "mProgressPosition: " + mProgressPosition);
        Log.d("Thiago", "position == mProgressPosition: " + (position == mProgressPosition));
        return position == mProgressPosition ? 1 : 0;
    }

    public void setRecyclerViewOnClickListenerHack(RecyclerViewOnClickListenerHack r){
        mRecyclerViewOnClickListenerHack = r;
    }

    public class PostViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {

        public TextView txtStatus;
        public TextView txtId;
        public TextView txtDate;
        public TextView txtName;
        public TextView txtSubject;
        public TextView txtLocale;
        public LinearLayout llContent;

        public PostViewHolder(View itemView) {
            super(itemView);

            llContent = (LinearLayout) itemView.findViewById(R.id.ll_content);
            txtStatus = (TextView) itemView.findViewById(R.id.txtStatus);
            txtId = (TextView) itemView.findViewById(R.id.txtId);
            txtDate = (TextView) itemView.findViewById(R.id.txtDate);
            txtName = (TextView) itemView.findViewById(R.id.txtName);
            txtSubject = (TextView) itemView.findViewById(R.id.txtSubject);
            txtLocale = (TextView) itemView.findViewById(R.id.txtLocale);

            itemView.setOnClickListener(this);
        }

        @Override
        public void onClick(View v) {
            if(mRecyclerViewOnClickListenerHack != null){
                mRecyclerViewOnClickListenerHack.onClickListener(v, getAdapterPosition());
            }
        }

        public void clearAnimation(){
            llContent.clearAnimation();
        }
    }

    public static class ProgressViewHolder extends RecyclerView.ViewHolder {
        public ProgressBar progressBar;
        public ProgressViewHolder(View v) {
            super(v);
            progressBar = (ProgressBar)v.findViewById(R.id.progress);
        }
    }

    private void setAnimation(View viewToAnimate, int position)
    {
        // If the bound view wasn't previously displayed on screen, it's animated
        Animation animation;

        if (position > mLastPosition){
//            Animation animation = AnimationUtils.loadAnimation(mCtx, android.R.anim.slide_in_left);
            animation = AnimationUtils.loadAnimation(mCtx, R.anim.slide_in_bottom);
        }
        else{
            animation = AnimationUtils.loadAnimation(mCtx, R.anim.slide_in_top);
        }

        mLastPosition = position;
        viewToAnimate.startAnimation(animation);
    }

    @Override
    public void onViewDetachedFromWindow(final RecyclerView.ViewHolder holder)
    {
        if(holder instanceof PostViewHolder){
            ((PostViewHolder)holder).clearAnimation();
        }
    }
}

Here is a gif of how the animation is behaving.

Does anyone have any idea what I'm doing wrong?

    
asked by anonymous 04.12.2016 / 19:03

0 answers