在为这CardView
个实现自定义动画之后,前两个没有按照应有的方式运行。项目A和项目B不会在第二次点击时展开,但项目C可以很好地工作。
public class MyRecyclerAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private static final int TYPE_HEADER = 0;
private static final int TYPE_ITEM = 1;
private Context mContext;
RecyclerViewHeader header;
List<MyRecyclerViewItem> listItems;
ValueAnimator mAnimator;
public MyRecyclerAdapter(Context context, RecyclerViewHeader header, List<MyRecyclerViewItem> listItems)
{
this.mContext = context;
this.header = header;
this.listItems = listItems;
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if(viewType == TYPE_HEADER)
{
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.recyclerview_header, parent, false);
return new MyRecyclerAdapter.VHHeader(v);
}
else if(viewType == TYPE_ITEM)
{
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.recyclerview_item, parent, false);
return new MyRecyclerAdapter.VHItem(v);
}
throw new RuntimeException("there is no type that matches the type " + viewType + " + make sure your using types correctly");
}
private MyRecyclerViewItem getItem(int position)
{
return listItems.get(position);
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
final Typeface iconFont = FontManager.getTypeface(mContext, FontManager.FONTAWESOME);
if (holder instanceof VHHeader)
{
final VHHeader vhHeader = (VHHeader)holder;
}
else if (holder instanceof VHItem)
{
MyRecyclerViewItem currentItem = getItem(position-1);
final VHItem vhItem = (VHItem)holder;
vhItem.txtA.setText(currentItem.getContinent());
vhItem.txtB.setText(currentItem.getCountry());
vhItem.txtB.setVisibility(View.GONE);
vhItem.txtExpandCollapse.setText(R.string.fa_icon_chevron_down);
vhItem.txtExpandCollapse.setTypeface(iconFont);
//Add onPreDrawListener
vhItem.txtB.getViewTreeObserver().addOnPreDrawListener(
new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
vhItem.txtB.getViewTreeObserver().removeOnPreDrawListener(this);
vhItem.txtB.setVisibility(View.GONE);
final int widthSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
final int heightSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
vhItem.txtB.measure(widthSpec, heightSpec);
mAnimator = vhItem.slideAnimator(0, vhItem.txtB.getMeasuredHeight());
return true;
}
});
vhItem.cardView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(vhItem.txtB.getVisibility() == View.GONE){
vhItem.expand();
} else {
vhItem.collapse();
}
}
});
}
}
@Override
public int getItemViewType(int position) {
if(isPositionHeader(position))
return TYPE_HEADER;
return TYPE_ITEM;
}
private boolean isPositionHeader(int position)
{
return position == 0;
}
// increasing getItemcount to 1. This will be the row of header.
@Override
public int getItemCount() {
return listItems.size()+1;
}
class VHHeader extends RecyclerView.ViewHolder{
Button btnCollapseAll, btnExpandAll;
public VHHeader(View headerView) {
super(headerView);
this.btnCollapseAll = headerView.findViewById(R.id.btn_collapseall);
this.btnExpandAll = headerView.findViewById(R.id.btn_expandall);
}
}
public class VHItem extends RecyclerView.ViewHolder{
CardView cardView;
RelativeLayout mRelativeLayout;
TextView txtExpandCollapse, txtA, txtB;
public VHItem(View itemView) {
super(itemView);
this.cardView = itemView.findViewById(R.id.cv);
this.mRelativeLayout = itemView.findViewById(R.id.tv_rv_relativelayout);
this.txtExpandCollapse = itemView.findViewById(R.id.tv_rv_expandcollapse);
this.txtA = itemView.findViewById(R.id.tv_rv_A);
this.txtB = itemView.findViewById(R.id.tv_rv_B);
}
private void expand() {
// set Visible
txtB.setVisibility(View.VISIBLE);
// change direction of chevron to 'up'
txtExpandCollapse.setText(R.string.fa_icon_chevron_up);
mAnimator.start();
}
private void collapse() {
// change direction of chevron to 'down'
txtExpandCollapse.setText(R.string.fa_icon_chevron_down);
int finalHeight = txtB.getHeight();
ValueAnimator mAnimator = slideAnimator(finalHeight, 0);
mAnimator.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationEnd(Animator animator) {
//Height=0, but it set visibility to GONE
txtB.setVisibility(View.GONE);
}
@Override
public void onAnimationStart(Animator animator) {
}
@Override
public void onAnimationCancel(Animator animator) {
}
@Override
public void onAnimationRepeat(Animator animator) {
}
});
mAnimator.start();
}
public ValueAnimator slideAnimator(int start, int end) {
ValueAnimator animator = ValueAnimator.ofInt(start, end);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
//Update Height
int value = (Integer) valueAnimator.getAnimatedValue();
ViewGroup.LayoutParams layoutParams = txtB.getLayoutParams();
layoutParams.height = value;
txtB.setLayoutParams(layoutParams);
}
});
return animator;
}
}
}
答案 0 :(得分:2)
您需要重新初始化mAnimator
对象。
尝试下面,
在VHItem类中定义另一个成员变量,以保持textB的高度
public class VHItem extends RecyclerView.ViewHolder{
CardView cardView;
RelativeLayout mRelativeLayout;
TextView txtExpandCollapse, txtA, txtB;
int textBHeight; // new variable
}
然后通过onPreDraw方法对其进行初始化
public boolean onPreDraw() {
vhItem.txtB.getViewTreeObserver().removeOnPreDrawListener(this);
vhItem.txtB.setVisibility(View.GONE);
final int widthSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
final int heightSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
vhItem.txtB.measure(widthSpec, heightSpec);
vhItem.textBHeight = vhItem.txtB.getMeasuredHeight();
return true;
}
然后在开始之前初始化动画制作器
private void expand() {
txtB.setVisibility(View.VISIBLE);
txtExpandCollapse.setText(R.string.fa_icon_chevron_up);
mAnimator = slideAnimator(0,textBHeight);
mAnimator.start();
}
答案 1 :(得分:0)
将对象CardView更改为View。
与其在cardview上生成事件,不如对内部类VHItem执行以下操作:
View view;
RelativeLayout mRelativeLayout;
TextView txtExpandCollapse, txtA, txtB;
public VHItem(View itemView) {
super(itemView);
this.view = itemView;
this.mRelativeLayout = itemView.findViewById(R.id.tv_rv_relativelayout);
this.txtExpandCollapse = itemView.findViewById(R.id.tv_rv_expandcollapse);
this.txtA = itemView.findViewById(R.id.tv_rv_A);
this.txtB = itemView.findViewById(R.id.tv_rv_B);
}
现在,在onBindViewHolder方法上:
vhItem.view.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v) {
if(vhItem.txtB.getVisibility() == View.GONE){
vhItem.expand();
} else {
vhItem.collapse();
}
}
});