Android动画回收查看

时间:2017-04-11 08:57:12

标签: android android-recyclerview recycler-adapter

我创建了一个包含'事件列表的回收者视图。这适用于低于5的事件列表。但是一旦我在列表中获得6个或更多事件,最后一个事件将单击时不展开,而是消失。结束动画也会停止处理列表中超过6个事件。

它应该如何表现:

  • 用户点击事件>视图扩展为全屏
  • 用户点击展开的事件>视图折叠回原来的大小
  • 用户在展开另一个事件时点击一个事件>展开事件设置为原始高度已点击事件扩展为全屏

目前的行为:

  • 用户点击事件>所有视图都会正确扩展,但列表中的最后一项除外
  • 用户点击展开的事件>查看折叠但不动画
  • 用户在展开另一个事件时点击一个事件>扩展事件折叠和tapped事件正确扩展
  • 用户点击列表中的最后一个事件>事件消失(可能将其大小降低到0以下)

我知道这可能与recyclelerview在屏幕外时重用其视图的方式有关。为了解决这个问题,我通过eventId检查tapped事件的位置,而不是列表中的位置,但这仍然留下了我上面谈到的问题。

public class EventRecyclerAdapter extends RecyclerView.Adapter<EventRecyclerAdapter.ViewHolder> {
    private Context c;
    private List<Event> items = new ArrayList<>();
    private RelativeLayout container;
    private int screenheight;
    private EventListFragment eventListFragment;
    private int expandedPosition = -1;
    private static final String TAG = "EventRecyclerAdapter";

    public interface ItemClickedListener {
        void itemClicked(int position);
    }

    private ItemClickedListener itemClickedListener;

    public EventRecyclerAdapter(List<Event> itemlist, Context c, EventListFragment eventListFragment, ItemClickedListener listener) {
        this.items = itemlist;
        this.c = c;
        this.eventListFragment = eventListFragment;
        this.itemClickedListener = listener;
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        // create a new view
        View itemLayoutView = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item, null);

        WindowManager wm = (WindowManager) c.getSystemService(Context.WINDOW_SERVICE);
        Display display = wm.getDefaultDisplay();
        Point size = new Point();
        display.getSize(size);
        screenheight = size.y;

        // Get the screen height from the device
        Resources r = c.getResources();
        float px = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 80, r.getDisplayMetrics());
        screenheight -= px;

        ViewHolder viewHolder = new ViewHolder(itemLayoutView);
        return viewHolder;
    }

    // Replace the contents of a view (invoked by the layout manager)
    @Override
    public void onBindViewHolder(ViewHolder viewHolder, int position) {
        Event event = items.get(position);
        // - get data from your itemsData at this position
        // - replace the contents of the view with that itemsData
        viewHolder.tvName.setText(event.getName());
        viewHolder.tvLocation.setText(event.getLocation().getName());
        viewHolder.tvDate.setText(Helper.dateDoubleToString(event.getStartDate()));
        viewHolder.tvTicketCount.setText(String.valueOf(event.getNumberOfTickets()));
        viewHolder.background.setBackgroundColor(Color.GRAY);
        viewHolder.eventId = event.getId();

        // Load the background image
        if (event.getEventImageId() != null) {
            Picasso.with(c).load(Helper.imageUrlString(event.getEventImageId())).into(viewHolder.background);
            ColorMatrix matrix = new ColorMatrix();
            matrix.setSaturation(0);

            ColorMatrixColorFilter filter = new ColorMatrixColorFilter(matrix);
            viewHolder.background.setColorFilter(filter);
        }

        // Check if the view needs to be expanded, collapsed or just drawn normally.
        if (expandedPosition == event.getId()) {
            if (event.expanded) {
                collapseView(viewHolder, event);
            } else if (!event.expanded) {
                expandView(viewHolder, position, event);
            }
        } else {
            setContainerHeight(viewHolder, event);
        }
    }

    private void expandView(final EventRecyclerAdapter.ViewHolder viewHolder, final int pos, Event event) {
        ResizeAnimation resizeAnimation = new ResizeAnimation(
                viewHolder.container,
                viewHolder.container.getHeight(),
                screenheight
        );
        resizeAnimation.setDuration(Constants.ANIMATION_SPEED);
        resizeAnimation.setAnimationListener(new Animation.AnimationListener() {
            @Override
            public void onAnimationStart(Animation animation) {
            }

            @Override
            public void onAnimationEnd(Animation animation) {
                viewHolder.infoContainer.setVisibility(View.VISIBLE);
                viewHolder.closeIcon.setVisibility(View.VISIBLE);
                itemClickedListener.itemClicked(pos);
            }

            @Override
            public void onAnimationRepeat(Animation animation) {
            }
        });
        viewHolder.itemView.startAnimation(resizeAnimation);
        viewHolder.expanded = true;

        event.expanded = true;
    }

    private void collapseView(final EventRecyclerAdapter.ViewHolder viewHolder, Event event) {
        ResizeAnimation resizeAnimation = new ResizeAnimation(
                viewHolder.container,
                viewHolder.container.getHeight(),
                getContainerCollapsedHeight()
        );
        resizeAnimation.setDuration(Constants.ANIMATION_SPEED);

        viewHolder.infoContainer.setVisibility(View.INVISIBLE);
        viewHolder.closeIcon.setVisibility(View.INVISIBLE);
        viewHolder.itemView.startAnimation(resizeAnimation);
        viewHolder.expanded = false;
        event.expanded = false;
}

    private void setContainerHeight(EventRecyclerAdapter.ViewHolder viewHolder, Event event) {
        viewHolder.container.setLayoutParams(new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, getContainerCollapsedHeight()));
        viewHolder.infoContainer.setVisibility(View.INVISIBLE);
        viewHolder.closeIcon.setVisibility(View.INVISIBLE);
        event.expanded = false;
        viewHolder.expanded = false;
    }

    private int getContainerCollapsedHeight() {
        int containerHeight;
        // Define the item containers height
        if (items.size() <= 3) {
            containerHeight = screenheight / items.size();
        } else {
            containerHeight = screenheight / 3;
        }
        return containerHeight;
    }

    /**
     * Clear all current data and swap add the new data list.
     * The expanded position also gets reset
     * @param events
     */
    public void swap(List<Event> events) {
        this.items.clear();
        this.items.addAll(events);
        this.expandedPosition = -1;

        Log.v(TAG,"SWAP SIZE : " + items.size());
        notifyDataSetChanged();
    }

    // inner class to hold a reference to each item of RecyclerView
    class ViewHolder extends RecyclerView.ViewHolder {

        public TextView tvLocation, tvDate, tvTicketCount;
        public TextView tvName;
        public ImageView background;
        public View container;
        public View infoContainer;
        public TextView closeIcon;
        public int eventId;
        public boolean expanded = false;

        public ViewHolder(final View itemLayoutView) {
            super(itemLayoutView);

            tvName = (TextView) itemLayoutView.findViewById(R.id.tvName);
            tvLocation = (TextView) itemLayoutView.findViewById(R.id.tvLocation);
            tvDate = (TextView) itemLayoutView.findViewById(R.id.tvDate);
            background = (ImageView) itemLayoutView.findViewById(R.id.background);
            tvTicketCount = (TextView) itemLayoutView.findViewById(R.id.ticket_count);
            container = itemLayoutView.findViewById(R.id.list_item_container);
            infoContainer = itemLayoutView.findViewById(R.id.info_container);
            closeIcon = (TextView) itemLayoutView.findViewById(R.id.close_icon);

            infoContainer.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    Activity mainActivity = (Activity) c;
                    FragmentManager fm = mainActivity.getFragmentManager();
                    //add
                    FragmentTransaction ft = fm.beginTransaction();
                    ft.setCustomAnimations(R.animator.slide_to_top, R.animator.slide_from_bottom);
                    ft.addToBackStack(ft.toString());
                    ft.add(R.id.content_frame, EventFragment.newInstance(items.get(getAdapterPosition())), Constants.EVENT_FRAGMENT_TAG);
                    //commit change
                    ft.commit();
                }
            });

            container.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    expandedPosition = eventId;
                    notifyDataSetChanged();
                }
            });
        }
    }

    // Return the size of your itemsData (invoked by the layout manager)
    @Override
    public int getItemCount() {
        return items.size();
    }
}

我认为当我点击列表中的最后一项时,以某种方式运行collapseView方法,导致其高度低于0.但是我无法弄清楚为什么这是发生。 我希望有人能够发现这里的错误。

1 个答案:

答案 0 :(得分:0)

您可以在recycleview项目的OnClilck中尝试这个

dbo