gpt4 book ai didi

java - 单击时 CardView 展开/折叠不正确

转载 作者:行者123 更新时间:2023-12-02 01:55:09 25 4
gpt4 key购买 nike

出于某种原因,Item C CardView 是唯一一个动画的 - 即使 Item BItem单击 CardView法语元音 CardView 不适用,因为它工作正常。有谁知道如何解决这个问题以便正确的 CardView 动画?

enter image description here

GridView 的 GridView 自定义类

public class GridViewCustom extends GridView {
public GridViewCustom(Context context) {
super(context);
}

public GridViewCustom(Context context, AttributeSet attrs) {
super(context, attrs);
}

public GridViewCustom(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int heightSpec;

if (getLayoutParams().height == AbsListView.LayoutParams.WRAP_CONTENT) {
heightSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
}
else {
//Any other height should be respected as is.
heightSpec = heightMeasureSpec;
}

super.onMeasure(widthMeasureSpec, heightSpec);
}
}

fragment 类

public class MyFragmentRV extends android.support.v4.app.Fragment {
private Boolean mCurrentValue;

public int mGridViewHeight;
public int txtSubtitleHeight;
private static final int ITEM_TYPE = 100;
private static final int HEADER_TYPE = 101;
private static final int HEADER_TYPE_2 = 102;
private static final int GRID_TYPE = 103;
ValueAnimator mAnimatorGV, mAnimatorTV;
TextView txtArrowGV, txtTitle;

static final String[] frenchVowels = new String[]{
"a", "e", "i", "o", "u", "y"
};

public MyFragmentRV.MyAdapter adapterGV;

public MyFragmentRV() {}

@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

return inflater.inflate(R.layout.fragment_rv, container, false);
}

@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
View v = getView();
assert v != null;

recyclerView = v.findViewById(R.id.my_recyclerview);

// set the linear layout manager
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false));

// SpannableStrings
int[] attrS = {R.attr.spannablestringtextColor};
TypedArray ta = getActivity().getTheme().obtainStyledAttributes(attrS);
int colorSS = ta.getColor(0, Color.BLACK); //Color.BLACK - default value (colour will change automatically depending on chosen theme)
Log.d(TAG, "clickMethod 1) " + Integer.toHexString(colorSS));
ta.recycle();

// SpannableString (start)
SpannableStringBuilder ssb = new SpannableStringBuilder();

SpannableString str1 = new SpannableString(" Item A ");
str1.setSpan(new BackgroundColorSpan(Color.BLACK), 0, str1.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
str1.setSpan(new ForegroundColorSpan(ContextCompat.getColor(getContext(), R.color.yellow)), 0, str1.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
ssb.append(str1);

SpannableString str2 = new SpannableString(" Hello World");
str2.setSpan(new ForegroundColorSpan(colorSS), 0, str2.length(), 0);
ssb.append(str2);
// SpannableString (end)

// init data
data = new ArrayList<>();
data.add(ssb);
data.add("Item B");
data.add("Item C");

subdata = new ArrayList<>();
subdata.add("\u2022 a");
subdata.add("\u2022 b\n\u2022 bb");
subdata.add("\u2022 c\n\u2022 cc\n\u2022 ccc");

adapter = createAdapter();

recyclerView.setAdapter(adapter);

super.onActivityCreated(savedInstanceState);
}

RecyclerView recyclerView;
ArrayList<CharSequence> data;
ArrayList<String> subdata;
RecyclerView.Adapter<ViewHolder> adapter;

// creates the adapter
private RecyclerView.Adapter<ViewHolder> createAdapter() {
return new RecyclerView.Adapter<ViewHolder>() {
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int type) {
switch (type) {
case HEADER_TYPE:
return new ViewHolder(inflateHelper(R.layout.header, parent));

case HEADER_TYPE_2:
return new ViewHolder(inflateHelper(R.layout.header, parent));

case ITEM_TYPE:
return new ViewHolder(inflateHelper(R.layout.recyclerview_item_tv, parent));

case GRID_TYPE:
return new ViewHolder(inflateHelper(R.layout.recyclerview_item_gv, parent));

default:
return new ViewHolder(inflateHelper(R.layout.recyclerview_item_tv, parent));
}
}

@Override
public void onBindViewHolder(@NonNull ViewHolder viewHolder, int position) {
final Typeface iconFont = FontManager.getTypeface(getContext(), FontManager.FONTAWESOME);

switch (getItemViewType(position)) {
case HEADER_TYPE:
Button expandButton = viewHolder.itemView.findViewById(R.id.button);
expandButton.setText("Expand all");
break;
case HEADER_TYPE_2:
Button collapseButton = viewHolder.itemView.findViewById(R.id.button);
collapseButton.setText("Collapse all");
break;
case ITEM_TYPE:
// get the current item
CharSequence itemA = data.get(position - 3);
String itemB = subdata.get(position - 3);

//
txtTitle = viewHolder.itemView.findViewById(R.id.tv_tv_A);
txtTitle.setText(itemA);

final TextView txtSubtitle = viewHolder.itemView.findViewById(R.id.tv_tv_B);
txtSubtitle.setText(itemB);
txtSubtitle.setVisibility(View.GONE);

//Add onPreDrawListener
txtSubtitle.getViewTreeObserver().addOnPreDrawListener(
new ViewTreeObserver.OnPreDrawListener() {

@Override
public boolean onPreDraw() {
txtSubtitle.getViewTreeObserver().removeOnPreDrawListener(this);
txtSubtitle.setVisibility(View.GONE);

final int widthSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
final int heightSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
txtSubtitle.measure(widthSpec, heightSpec);

txtSubtitleHeight = txtSubtitle.getMeasuredHeight();

return true;
}
});

final TextView txtArrowTV = viewHolder.itemView.findViewById(R.id.tv_tv_expandcollapse);
txtArrowTV.setText(R.string.fa_icon_chevron_down);
txtArrowTV.setTypeface(iconFont);

//
CardView cardView = viewHolder.itemView.findViewById(R.id.cv_tv);
LinearLayout mLinearLayoutTV = viewHolder.itemView.findViewById(R.id.cardview_tv_titlerow);

//
cardView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(txtSubtitle.getVisibility() == View.GONE){
expandTV(txtSubtitle, txtArrowTV);
} else {
collapseTV(txtSubtitle, txtArrowTV);
}
}
});

mLinearLayoutTV.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(txtSubtitle.getVisibility() == View.GONE){
expandTV(txtSubtitle, txtArrowTV);
} else {
collapseTV(txtSubtitle, txtArrowTV);
}
}
});

txtArrowTV.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(txtSubtitle.getVisibility() == View.GONE){
expandTV(txtSubtitle, txtArrowTV);
} else {
collapseTV(txtSubtitle, txtArrowTV);
}
}
});
break;
case GRID_TYPE:
TextView titleG = viewHolder.itemView.findViewById(R.id.tv_gv_A);

titleG.setText("French vowels");

txtArrowGV = viewHolder.itemView.findViewById(R.id.tv_gv_expandcollapse);
txtArrowGV.setText(R.string.fa_icon_chevron_down);
txtArrowGV.setTypeface(iconFont);

final GridView mGridViewA = viewHolder.itemView.findViewById(R.id.gv);
mGridViewA.setVisibility(View.GONE);
mGridViewA.setEnabled(false);
mGridViewA.setVerticalScrollBarEnabled(false);
adapterGV = new MyFragmentRV.MyAdapter(getActivity().getApplicationContext(), 0);
mGridViewA.setAdapter(adapterGV);
for (String fVowel : fVowels) {
adapterGV.addAdapterItem(new MyFragmentRV.AdapterItem(fVowel));
}


//Add onPreDrawListener
mGridViewA.getViewTreeObserver().addOnPreDrawListener(
new ViewTreeObserver.OnPreDrawListener() {

@Override
public boolean onPreDraw() {
mGridViewA.getViewTreeObserver().removeOnPreDrawListener(this);
mGridViewA.setVisibility(View.GONE);

final int widthSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
final int heightSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
mGridViewA.measure(widthSpec, heightSpec);

mGridViewHeight = mGridViewA.getMeasuredHeight();

return true;
}
});

CardView cardViewG = viewHolder.itemView.findViewById(R.id.cv_gv);
LinearLayout mLinearLayoutGV = viewHolder.itemView.findViewById(R.id.cardview_gv_titlerow);

cardViewG.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(mGridViewA.getVisibility() == View.GONE){
expandGV(mGridViewA);
} else {
collapseGV(mGridViewA);
}
}
});

mLinearLayoutGV.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(mGridViewA.getVisibility() == View.GONE){
expandGV(mGridViewA);
} else {
collapseGV(mGridViewA);
}
}
});

txtArrowGV.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(mGridViewA.getVisibility() == View.GONE){
expandGV(mGridViewA);
} else {
collapseGV(mGridViewA);
}
}
});
break;
}
}

@Override
public int getItemCount() {
return data.size() + 3;
}

@Override
public int getItemViewType(int position) {
switch (position) {
case 0:
return HEADER_TYPE;
case 1:
return HEADER_TYPE_2;
case 2:
return GRID_TYPE;
default: return ITEM_TYPE;
}
}
};
}

private View inflateHelper(int resId, ViewGroup parent) {
return LayoutInflater.from(getActivity()).inflate(resId, parent, false);
}

class ViewHolder extends RecyclerView.ViewHolder {
public ViewHolder(@NonNull View itemView) {
super(itemView);
}
}

public void expandGV() {
mGridViewA.setVisibility(View.VISIBLE);
txtArrowGV.setText(R.string.fa_icon_chevron_up);
ValueAnimator mAnimatorGV = slideAnimator(0, mGridViewHeight);
mAnimatorGV.start();
}
public void collapseGV() {
txtArrowGV.setText(R.string.fa_icon_chevron_down);

int finalGVHeight = mGridViewA.getHeight();

mAnimatorGV = slideAnimator(finalGVHeight, 0);
mAnimatorGV.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationEnd(Animator animator) {
mGridViewA.setVisibility(View.GONE);
}

@Override
public void onAnimationStart(Animator animator) {
}

@Override
public void onAnimationCancel(Animator animator) {
}

@Override
public void onAnimationRepeat(Animator animator) {
}
});
mAnimatorGV.start();
}
public void expandTV() {
txtSubtitle.setVisibility(View.VISIBLE);
txtArrowTV.setText(R.string.fa_icon_chevron_up);
mAnimatorTV = slideAnimator(0, txtSubtitleHeight);
mAnimatorTV.start();
}
public void collapseTV() {
txtArrowTV.setText(R.string.fa_icon_chevron_down);
int finalTVHeight = txtSubtitle.getHeight();
mAnimatorTV = slideAnimator(finalTVHeight, 0);
mAnimatorTV.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationEnd(Animator animator) {
txtSubtitle.setVisibility(View.GONE);
}

@Override
public void onAnimationStart(Animator animator) {
}

@Override
public void onAnimationCancel(Animator animator) {
}

@Override
public void onAnimationRepeat(Animator animator) {
}
});
mAnimatorTV.start();
}

public ValueAnimator slideAnimator(int start, int end, final View txtSubtitle) {

final 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 layoutParamsTV = txtSubtitle.getLayoutParams();
layoutParamsTV.height = value;
txtSubtitle.setLayoutParams(layoutParamsTV);
}
});
return animator;
}

/// Adapter for GridView
private class MyAdapter extends ArrayAdapter<MyFragmentRV.AdapterItem> {
private List<MyFragmentRV.AdapterItem> items = new ArrayList<>();

MyAdapter(Context context, int textviewid) {
super(context, textviewid);
}

void addAdapterItem(MyFragmentRV.AdapterItem item) {
items.add(item);
}

@Override
public int getCount() {
return items.size();
}

@Override
public MyFragmentRV.AdapterItem getItem(int position) {
return ((null != items) ? items.get(position) : null);
}

@Override
public long getItemId(int position) {
return position;
}

@NonNull
@Override
public View getView(final int position, View convertView, @NonNull final ViewGroup parent) {
View rowView;
if (convertView == null) {
rowView = getActivity().getLayoutInflater().inflate(R.layout.gridview_item, parent, false);
} else {
rowView = convertView;
}

TextView tv = rowView.findViewById(R.id.item_gridview);
tv.setText(items.get(position).first);

return rowView;
}
}

public class AdapterItem {
String first;

//add more items
AdapterItem(String first) {
this.first = first;
}
}
}

基于 Nikhil 的建议

enter image description here

最佳答案

这里的问题是您将 txtSubtitle 存储为 Fragment 的成员变量。因此,当 GridView 完成网格项的初始化后,txtSubtitle 将具有最后分配的 TextView,在您的情况下为 Item C。因此,当您执行动画时,它始终会应用于项目 C。这里的解决方案是使 txtSubtitle 成为 local Final 变量。从 MyFragmentRV 中删除 TextView txtArrowGV、txtArrowTV、txtTitle、txtSubtitle;。如果ITEM_TYPE:

final TextView txtSubtitle = viewHolder.itemView.findViewById(R.id.tv_tv_B);
....


cardView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(txtSubtitle.getVisibility() == View.GONE){
expandTV(txtSubtitle);
} else {
collapseTV(txtSubtitle);
}
}
});

txtSubtitle 传递到 expandTVcollapseTVexpandTV 中:

public void expandTV(TextView txtSubtitle) {
txtSubtitle.setVisibility(View.VISIBLE);
txtArrowTV.setText(R.string.fa_icon_chevron_up);
mAnimatorTV = slideAnimator(0, txtSubtitleHeight);
mAnimatorTV.start();
}

编辑:将幻灯片动画器功能更改为:

public ValueAnimator slideAnimator(int start, int end,TextView txtSubtitle) {

final 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 layoutParamsTV = txtSubtitle.getLayoutParams();
layoutParamsTV.height = value;
txtSubtitle.setLayoutParams(layoutParamsTV);
}
});
return animator;
}

并这样调用它:

mAnimatorTV = slideAnimator(0, txtSubtitleHeight,txtSubtitle);
mAnimatorTV.start();

关于java - 单击时 CardView 展开/折叠不正确,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52412450/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com