Skip to content

Commit b0d7408

Browse files
author
luobl
committed
修复高度设置wrap_content显示不全的bug
1 parent b71b511 commit b0d7408

File tree

2 files changed

+129
-87
lines changed

2 files changed

+129
-87
lines changed

readme.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323

2424
##问题
2525

26-
- `CardView`高度设置为`wrap_content`卡片会显示不全。
26+
- `CardView`高度设置为`wrap_content`卡片会显示不全。(已修复)
2727
- `CardView`设置`padding``margin`,旋转动画会有被截断的效果。最后一张卡片距离顶部的距离是在CardView内部指定的,为固定值。
2828
- 测试2.3.2有严重bug(估计4.0版本之前都有此bug),不可用。
2929

src/com/chiemy/cardview/view/CardView.java

Lines changed: 128 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,48 @@
11
package com.chiemy.cardview.view;
22

33
import android.content.Context;
4-
import android.content.res.TypedArray;
54
import android.database.DataSetObserver;
65
import android.graphics.Rect;
76
import android.util.AttributeSet;
7+
import android.util.Log;
88
import android.util.SparseArray;
99
import android.view.MotionEvent;
1010
import android.view.View;
1111
import android.view.ViewConfiguration;
12+
import android.view.ViewGroup;
13+
import android.view.View.MeasureSpec;
1214
import android.view.animation.AccelerateInterpolator;
1315
import android.widget.FrameLayout;
1416
import android.widget.ListAdapter;
1517

16-
import com.chiemy.cardview.Utils;
1718
import com.nineoldandroids.animation.Animator;
1819
import com.nineoldandroids.animation.AnimatorListenerAdapter;
1920
import com.nineoldandroids.view.ViewHelper;
2021
import com.nineoldandroids.view.ViewPropertyAnimator;
2122

2223
/**
2324
* @author chiemy
24-
*
25+
*
2526
*/
26-
public class CardView extends FrameLayout{
27+
public class CardView extends FrameLayout {
2728
private static final int ITEM_SPACE = 40;
2829
private static final int DEF_MAX_VISIBLE = 4;
29-
private static final int PADDING_TOP = 20;
30-
30+
3131
private int mMaxVisible = DEF_MAX_VISIBLE;
3232
private int itemSpace = ITEM_SPACE;
33-
33+
3434
private float mTouchSlop;
3535
private ListAdapter mListAdapter;
3636
private int mNextAdapterPosition;
3737
private SparseArray<View> viewHolder = new SparseArray<View>();
3838
private OnCardClickListener mListener;
3939
private int topPosition;
4040
private Rect topRect;
41-
42-
public interface OnCardClickListener{
43-
void onCardClick(View view,int position);
41+
42+
public interface OnCardClickListener {
43+
void onCardClick(View view, int position);
4444
}
45-
45+
4646
public CardView(Context context, AttributeSet attrs, int defStyle) {
4747
super(context, attrs, defStyle);
4848
init();
@@ -57,35 +57,35 @@ public CardView(Context context) {
5757
super(context);
5858
init();
5959
}
60-
60+
6161
private void init() {
6262
topRect = new Rect();
6363
ViewConfiguration con = ViewConfiguration.get(getContext());
6464
mTouchSlop = con.getScaledTouchSlop();
6565
}
66-
66+
6767
public void setMaxVisibleCount(int count) {
6868
mMaxVisible = count;
6969
}
70-
70+
7171
public int getMaxVisibleCount() {
72-
return mMaxVisible;
72+
return mMaxVisible;
7373
}
74-
74+
7575
public void setItemSpace(int itemSpace) {
7676
this.itemSpace = itemSpace;
7777
}
78-
78+
7979
public int getItemSpace() {
8080
return itemSpace;
8181
}
82-
82+
8383
public ListAdapter getAdapter() {
8484
return mListAdapter;
8585
}
86-
86+
8787
public void setAdapter(ListAdapter adapter) {
88-
if (mListAdapter != null){
88+
if (mListAdapter != null) {
8989
mListAdapter.unregisterDataSetObserver(mDataSetObserver);
9090
}
9191
mNextAdapterPosition = 0;
@@ -94,56 +94,93 @@ public void setAdapter(ListAdapter adapter) {
9494
removeAllViews();
9595
ensureFull();
9696
}
97-
97+
9898
public void setOnCardClickListener(OnCardClickListener listener) {
9999
mListener = listener;
100100
}
101-
101+
102102
private void ensureFull() {
103103
while (mNextAdapterPosition < mListAdapter.getCount()
104104
&& getChildCount() < mMaxVisible) {
105105
int index = mNextAdapterPosition % mMaxVisible;
106106
View convertView = viewHolder.get(index);
107-
final View view = mListAdapter.getView(mNextAdapterPosition, convertView, this);
107+
final View view = mListAdapter.getView(mNextAdapterPosition,
108+
convertView, this);
108109
view.setOnClickListener(null);
110+
// view.setOnTouchListener(null);
109111
viewHolder.put(index, view);
110-
111-
//添加剩余的View时,始终处在最后
112+
113+
// 添加剩余的View时,始终处在最后
112114
index = Math.min(mNextAdapterPosition, mMaxVisible - 1);
113-
ViewHelper.setScaleX(view, ((mMaxVisible - index - 1)/(float)mMaxVisible)*0.2f + 0.8f);
114-
int topMargin = (mMaxVisible - index - 1)*itemSpace + PADDING_TOP;
115+
ViewHelper.setScaleX(view,((mMaxVisible - index - 1) / (float) mMaxVisible) * 0.2f + 0.8f);
116+
int topMargin = (mMaxVisible - index - 1) * itemSpace;
115117
ViewHelper.setTranslationY(view, topMargin);
116118
ViewHelper.setAlpha(view, mNextAdapterPosition == 0 ? 1 : 0.5f);
117-
119+
118120
LayoutParams params = (LayoutParams) view.getLayoutParams();
119-
if(params == null){
120-
params = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
121+
if (params == null) {
122+
params = new LayoutParams(LayoutParams.MATCH_PARENT,
123+
LayoutParams.WRAP_CONTENT);
121124
}
122-
addViewInLayout(view,0, params, true);
123-
125+
addViewInLayout(view, 0, params);
126+
124127
mNextAdapterPosition += 1;
125128
}
126-
requestLayout();
129+
// requestLayout();
130+
}
131+
132+
@Override
133+
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
134+
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
135+
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
136+
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
137+
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
138+
139+
int childCount = getChildCount();
140+
int maxHeight = 0;
141+
int maxWidth = 0;
142+
for (int i = 0; i < childCount; i++) {
143+
View child = getChildAt(i);
144+
this.measureChild(child, widthMeasureSpec, heightMeasureSpec);
145+
int height = child.getMeasuredHeight();
146+
int width = child.getMeasuredWidth();
147+
if (height > maxHeight) {
148+
maxHeight = height;
149+
}
150+
if (width > maxWidth) {
151+
maxWidth = width;
152+
}
153+
}
154+
int desireWidth = widthSize;
155+
int desireHeight = heightSize;
156+
if (widthMode == MeasureSpec.AT_MOST) {
157+
desireWidth = maxWidth + getPaddingLeft() + getPaddingRight();
158+
}
159+
if (heightMode == MeasureSpec.AT_MOST) {
160+
desireHeight = maxHeight + (mMaxVisible - 1) * itemSpace + getPaddingTop() + getPaddingBottom();
161+
}
162+
setMeasuredDimension(desireWidth, desireHeight);
127163
}
128-
164+
129165
@Override
130166
protected void onLayout(boolean changed, int left, int top, int right,
131167
int bottom) {
132168
super.onLayout(changed, left, top, right, bottom);
133-
View topView = getChildAt(getChildCount()-1);
134-
if(topView != null){
169+
View topView = getChildAt(getChildCount() - 1);
170+
if (topView != null) {
135171
topView.setOnClickListener(listener);
136172
}
137173
}
138-
139-
float downX,downY;
174+
175+
float downX, downY;
140176
boolean remove = false;
177+
141178
@Override
142179
public boolean onTouchEvent(MotionEvent event) {
143-
switch(event.getAction()){
180+
switch (event.getAction()) {
144181
case MotionEvent.ACTION_MOVE:
145-
if(!remove){
146-
if(goDown()){
182+
if (!remove) {
183+
if (goDown()) {
147184
downY = -1;
148185
remove = true;
149186
}
@@ -152,98 +189,103 @@ public boolean onTouchEvent(MotionEvent event) {
152189
}
153190
return super.onTouchEvent(event);
154191
}
155-
192+
156193
/**
157194
* 下移所有视图
158195
*/
159196
private boolean goDown() {
160197
final View topView = getChildAt(getChildCount() - 1);
161-
//topView.getHitRect(topRect); 在4.3以前有bug,用以下方法代替
198+
// topView.getHitRect(topRect); 在4.3以前有bug,用以下方法代替
162199
topRect = getHitRect(topRect, topView);
163-
//如果按下的位置不在顶部视图上,则不移动
164-
if(!topRect.contains((int)downX, (int)downY)){
200+
// 如果按下的位置不在顶部视图上,则不移动
201+
if (!topRect.contains((int) downX, (int) downY)) {
165202
return false;
166203
}
167-
ViewPropertyAnimator anim = ViewPropertyAnimator.animate(topView)
168-
.translationY(ViewHelper.getTranslationY(topView) + topView.getHeight())
169-
.alpha(0).scaleX(1)
170-
.setListener(null)
171-
.setDuration(200);
204+
ViewPropertyAnimator anim = ViewPropertyAnimator
205+
.animate(topView)
206+
.translationY(
207+
ViewHelper.getTranslationY(topView)
208+
+ topView.getHeight()).alpha(0).scaleX(1)
209+
.setListener(null).setDuration(200);
172210
anim.setListener(new AnimatorListenerAdapter() {
173211
@Override
174212
public void onAnimationEnd(Animator animation) {
175213
removeView(topView);
176214
ensureFull();
177215
final int count = getChildCount();
178-
for(int i = 0 ; i < count ; i++){
216+
for (int i = 0; i < count; i++) {
179217
final View view = getChildAt(i);
180-
float scaleX = ViewHelper.getScaleX(view) + ((float)1/mMaxVisible)*0.2f;
181-
float tranlateY = ViewHelper.getTranslationY(view) + itemSpace;
182-
if(i == count - 1){
218+
float scaleX = ViewHelper.getScaleX(view)
219+
+ ((float) 1 / mMaxVisible) * 0.2f;
220+
float tranlateY = ViewHelper.getTranslationY(view)
221+
+ itemSpace;
222+
if (i == count - 1) {
183223
bringToTop(view);
184-
}else{
185-
if((count == mMaxVisible && i != 0) || count < mMaxVisible){
186-
ViewPropertyAnimator.animate(view)
187-
.translationY(tranlateY)
188-
.setInterpolator(new AccelerateInterpolator())
189-
.setListener(null)
190-
.scaleX(scaleX).setDuration(200);
224+
} else {
225+
if ((count == mMaxVisible && i != 0)
226+
|| count < mMaxVisible) {
227+
ViewPropertyAnimator
228+
.animate(view)
229+
.translationY(tranlateY)
230+
.setInterpolator(
231+
new AccelerateInterpolator())
232+
.setListener(null).scaleX(scaleX)
233+
.setDuration(200);
191234
}
192235
}
193236
}
194237
}
195238
});
196239
return true;
197240
}
198-
241+
199242
/**
200243
* 将下一个视图移到前边
244+
*
201245
* @param view
202246
*/
203247
private void bringToTop(final View view) {
204-
float scaleX = ViewHelper.getScaleX(view) + ((float)1/mMaxVisible)*0.2f;
248+
float scaleX = ViewHelper.getScaleX(view) + ((float) 1 / mMaxVisible)
249+
* 0.2f;
205250
float tranlateY = ViewHelper.getTranslationY(view) + itemSpace;
206-
ViewPropertyAnimator.animate(view)
207-
.translationY(tranlateY)
208-
.scaleX(scaleX)
209-
.setDuration(200)
210-
.alpha(1).setInterpolator(new AccelerateInterpolator())
211-
.setListener(null)
212-
.setListener(new AnimatorListenerAdapter() {
213-
public void onAnimationEnd(Animator animation) {
214-
topPosition++;
215-
remove = false;
216-
}
217-
});
251+
ViewPropertyAnimator.animate(view).translationY(tranlateY)
252+
.scaleX(scaleX).setDuration(200).alpha(1)
253+
.setInterpolator(new AccelerateInterpolator())
254+
.setListener(null).setListener(new AnimatorListenerAdapter() {
255+
public void onAnimationEnd(Animator animation) {
256+
topPosition++;
257+
remove = false;
258+
}
259+
});
218260
}
219-
220-
261+
221262
@Override
222263
public boolean onInterceptTouchEvent(MotionEvent ev) {
223264
float currentY = ev.getY();
224-
switch(ev.getAction()){
265+
switch (ev.getAction()) {
225266
case MotionEvent.ACTION_DOWN:
226267
downX = ev.getX();
227268
downY = ev.getY();
228269
break;
229270
case MotionEvent.ACTION_MOVE:
230271
float distance = currentY - downY;
231-
if(distance > mTouchSlop){
272+
if (distance > mTouchSlop) {
232273
return true;
233274
}
234275
break;
235276
}
236-
return super.onInterceptTouchEvent(ev);
277+
return false;
237278
}
238-
239-
public static Rect getHitRect(Rect rect,View child){
279+
280+
public static Rect getHitRect(Rect rect, View child) {
240281
rect.left = child.getLeft();
241282
rect.right = child.getRight();
242283
rect.top = (int) (child.getTop() + ViewHelper.getTranslationY(child));
243-
rect.bottom = (int) (child.getBottom() + ViewHelper.getTranslationY(child));
284+
rect.bottom = (int) (child.getBottom() + ViewHelper
285+
.getTranslationY(child));
244286
return rect;
245287
}
246-
288+
247289
private final DataSetObserver mDataSetObserver = new DataSetObserver() {
248290
@Override
249291
public void onChanged() {
@@ -255,11 +297,11 @@ public void onInvalidated() {
255297
super.onInvalidated();
256298
}
257299
};
258-
300+
259301
private OnClickListener listener = new OnClickListener() {
260302
@Override
261303
public void onClick(View v) {
262-
if(mListener != null){
304+
if (mListener != null) {
263305
mListener.onCardClick(v, topPosition);
264306
}
265307
}

0 commit comments

Comments
 (0)