4
我創建了一個包含「events」列表的recyclerview。這對於低於5的事件列表正常工作,但只要列表中有6個或更多事件,最後一個事件不會展開當點擊時,反而消失。關閉動畫也停止工作,列表中有6個以上的事件。Android animating recyclerview
應該如何表現:
- 用戶點擊事件>視圖擴展到整個屏幕
- 用戶點擊展開事件>視圖摺疊回它的原始尺寸
- 用戶點擊,而另一個事件的事件:展開>連接竊聽事件展開爲全屏
當前的行爲展開事件設置爲原來的高度3210
- 用戶點擊事件>所有視圖正確地擴大,除了在列表中的最後一個項目
- 用戶點擊展開的事件>查看倒塌,但沒有動畫
- 用戶點擊一個事件,而另一事件展開>展開事件崩塌,竊聽事件正確擴展
- 用戶點擊的最後一個事件列表>事件自敗(可能降低它的尺寸小於0)
我知道它可能有一些做的方式recyclerview再利用其觀點當他們不在屏幕上時。爲了解決這個問題,我使用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。但我無法弄清楚爲什麼發生這種情況。 我希望有人能夠發現這裏有什麼問題。
感謝您的答覆,但我不想活動之間的過渡。它只能將行的高度增加到全屏的高度,用戶仍然可以滾動瀏覽列表的其餘部分。 –