Java kikoso/swipeable卡android
嘿,我试过kikose/swipeable卡库,但它的性能不好(甚至在Nexus5上也落后)。我尝试将cardContainer类中的MMAXsible从3更改为2。性能有所提高,但仍然滞后,因此我将其更改为1,并且在第一张卡上的性能看起来非常出色。我刷了第一张卡后,第二张卡就不能刷了。cardcontainer类中的mTopCard为空。我如何解决这个问题或以其他方式提高性能 以下是cardcontainer类:Java kikoso/swipeable卡android,java,android,performance,github,Java,Android,Performance,Github,嘿,我试过kikose/swipeable卡库,但它的性能不好(甚至在Nexus5上也落后)。我尝试将cardContainer类中的MMAXsible从3更改为2。性能有所提高,但仍然滞后,因此我将其更改为1,并且在第一张卡上的性能看起来非常出色。我刷了第一张卡后,第二张卡就不能刷了。cardcontainer类中的mTopCard为空。我如何解决这个问题或以其他方式提高性能 以下是cardcontainer类: public class CardContainer extends Adapt
public class CardContainer extends AdapterView<ListAdapter> {
public static final int INVALID_POINTER_ID = -1;
private int mActivePointerId = INVALID_POINTER_ID;
private static final double DISORDERED_MAX_ROTATION_RADIANS = Math.PI / 64;
private int mNumberOfCards = -1;
Context context;
private final DataSetObserver mDataSetObserver = new DataSetObserver() {
@Override
public void onChanged() {
super.onChanged();
clearStack();
ensureFull();
}
@Override
public void onInvalidated() {
super.onInvalidated();
clearStack();
}
};
private final Random mRandom = new Random();
private final Rect boundsRect = new Rect();
private final Rect childRect = new Rect();
private final Matrix mMatrix = new Matrix();
//TODO: determine max dynamically based on device speed
private int mMaxVisible =2;
private GestureDetector mGestureDetector;
private int mFlingSlop;
private Orientation mOrientation;
private ListAdapter mListAdapter;
private float mLastTouchX;
private float mLastTouchY;
private View mTopCard;
private int mTouchSlop;
private int mGravity;
private int mNextAdapterPosition;
private boolean mDragging;
private boolean animating;
int index;
Profile cardModel;
public CardContainer(Context context) {
super(context);
this.context = context;
setOrientation(Orientation.Disordered);
setGravity(Gravity.TOP);
init();
animating = false;
}
public CardContainer(Context context, AttributeSet attrs) {
super(context, attrs);
this.context = context;
initFromXml(attrs);
init();
}
public CardContainer(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
this.context = context;
initFromXml(attrs);
init();
}
private void init() {
ViewConfiguration viewConfiguration = ViewConfiguration
.get(getContext());
mFlingSlop = viewConfiguration.getScaledMinimumFlingVelocity();
mTouchSlop = viewConfiguration.getScaledTouchSlop();
mGestureDetector = new GestureDetector(getContext(),
new GestureListener());
}
private void initFromXml(AttributeSet attr) {
TypedArray a = getContext().obtainStyledAttributes(attr,
R.styleable.CardContainer);
setGravity(a.getInteger(R.styleable.CardContainer_android_gravity,
Gravity.TOP));
int orientation = a
.getInteger(R.styleable.CardContainer_orientation, 1);
setOrientation(Orientation.fromIndex(orientation));
index = 0;
a.recycle();
}
@Override
public ListAdapter getAdapter() {
return mListAdapter;
}
@Override
public void setAdapter(ListAdapter adapter) {
index = 0;
if (mListAdapter != null)
mListAdapter.unregisterDataSetObserver(mDataSetObserver);
clearStack();
mTopCard = null;
mListAdapter = adapter;
mNextAdapterPosition = 0;
adapter.registerDataSetObserver(mDataSetObserver);
ensureFull();
Log.e("GETCHILD CARD CONT","getChildAt(getChildCount() - 1)==================="+getChildAt(getChildCount() - 1));
Log.e("GETCHILD CARD CONT","getChildCount()==================="+getChildCount());
if (getChildCount() != 0) {
mTopCard = getChildAt(getChildCount() - 1);
mTopCard.setLayerType(LAYER_TYPE_HARDWARE, null);
}
mNumberOfCards = getAdapter().getCount();
requestLayout();
((Profile)adapter.getItem(0)).getOnCardDimissedListener().initialiseCard();
}
private void ensureFull() {
while (mNextAdapterPosition < mListAdapter.getCount() && getChildCount() < mMaxVisible) {
View view = mListAdapter.getView(mNextAdapterPosition, null, this);
view.setLayerType(LAYER_TYPE_SOFTWARE, null);
if(mOrientation == Orientation.Disordered) {
view.setRotation(getDisorderedRotation());
}
addViewInLayout(view, 0, new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT,
mListAdapter.getItemViewType(mNextAdapterPosition)), false);
requestLayout();
mNextAdapterPosition += 1;
}
}
private void clearStack() {
removeAllViewsInLayout();
mNextAdapterPosition = 0;
mTopCard = null;
}
public Orientation getOrientation() {
return mOrientation;
}
public void setOrientation(Orientation orientation) {
if (orientation == null)
throw new NullPointerException("Orientation may not be null");
if(mOrientation != orientation) {
this.mOrientation = orientation;
if(orientation == Orientation.Disordered) {
for (int i = 0; i < getChildCount(); i++) {
View child = getChildAt(i);
child.setRotation(getDisorderedRotation());
}
}
else {
for (int i = 0; i < getChildCount(); i++) {
View child = getChildAt(i);
child.setRotation(0);
}
}
requestLayout();
}
}
private float getDisorderedRotation() {
return (float) Math.toDegrees(mRandom.nextGaussian() * DISORDERED_MAX_ROTATION_RADIANS);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int requestedWidth = getMeasuredWidth() - getPaddingLeft() - getPaddingRight();
int requestedHeight = getMeasuredHeight() - getPaddingTop() - getPaddingBottom();
int childWidth, childHeight;
if (mOrientation == Orientation.Disordered) {
int R1, R2;
if (requestedWidth >= requestedHeight) {
R1 = requestedHeight;
R2 = requestedWidth;
} else {
R1 = requestedWidth;
R2 = requestedHeight;
}
childWidth = (int) ((R1 * Math.cos(DISORDERED_MAX_ROTATION_RADIANS) - R2 * Math.sin(DISORDERED_MAX_ROTATION_RADIANS)) / Math.cos(2 * DISORDERED_MAX_ROTATION_RADIANS));
childHeight = (int) ((R2 * Math.cos(DISORDERED_MAX_ROTATION_RADIANS) - R1 * Math.sin(DISORDERED_MAX_ROTATION_RADIANS)) / Math.cos(2 * DISORDERED_MAX_ROTATION_RADIANS));
} else {
childWidth = requestedWidth;
childHeight = requestedHeight;
}
int childWidthMeasureSpec, childHeightMeasureSpec;
childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(childWidth, MeasureSpec.AT_MOST);
childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(childHeight, MeasureSpec.AT_MOST);
for (int i = 0; i < getChildCount(); i++) {
View child = getChildAt(i);
assert child != null;
child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
}
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
for (int i = 0; i < getChildCount(); i++) {
boundsRect.set(0, 0, getWidth(), getHeight());
View view = getChildAt(i);
int w, h;
w = view.getMeasuredWidth();
h = view.getMeasuredHeight();
Gravity.apply(mGravity, w, h, boundsRect, childRect);
view.layout(childRect.left, childRect.top, childRect.right, childRect.bottom);
}
}
int holdingCard;
View likeImage, dislikeImage;
@Override
public boolean onTouchEvent(MotionEvent event) {
if (mTopCard == null || animating) {
return false;
}
if (mGestureDetector.onTouchEvent(event)) {
return true;
}
final int pointerIndex;
final float x, y;
final float dx, dy;
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
getHitRect(mTopCard,childRect);
pointerIndex = event.getActionIndex();
x = event.getX(pointerIndex);
y = event.getY(pointerIndex);
if (!childRect.contains((int) x, (int) y)) {
return false;
}
mLastTouchX = x;
mLastTouchY = y;
mActivePointerId = event.getPointerId(pointerIndex);
float[] points = new float[]{x - mTopCard.getLeft(), y - mTopCard.getTop()};
mTopCard.getMatrix().invert(mMatrix);
mMatrix.mapPoints(points);
mTopCard.setPivotX(points[0]);
mTopCard.setPivotY(points[1]);
break;
case MotionEvent.ACTION_MOVE:
pointerIndex = event.findPointerIndex(mActivePointerId);
x = event.getX(pointerIndex);
y = event.getY(pointerIndex);
dx = x - mLastTouchX;
dy = y - mLastTouchY;
Profile profile = (Profile) getAdapter().getItem(0);
likeImage = mTopCard.findViewById(R.id.like_text_image);
dislikeImage = mTopCard.findViewById(R.id.dislike_text_image);
if (mTopCard.getTranslationX() + dx > 30) {
profile.getOnCardDimissedListener().tendToLike();
dislikeImage.setVisibility(View.INVISIBLE);
likeImage.setVisibility(View.VISIBLE);
}
else if (mTopCard.getTranslationX() + dx < 30) {
profile.getOnCardDimissedListener().tendToDislike();
likeImage.setVisibility(View.INVISIBLE);
dislikeImage.setVisibility(View.VISIBLE);
} else {
likeImage.setVisibility(View.INVISIBLE);
dislikeImage.setVisibility(View.INVISIBLE);
}
if (Math.abs(dx) > mTouchSlop || Math.abs(dy) > mTouchSlop) {
mDragging = true;
}
if(!mDragging) {
return true;
}
mTopCard.setTranslationX(mTopCard.getTranslationX() + dx);
mTopCard.setTranslationY(mTopCard.getTranslationY() + dy);
mTopCard.setRotation(40 * mTopCard.getTranslationX() / (getWidth() / 2.f));
mLastTouchX = x;
mLastTouchY = y;
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
if (!mDragging) {
return true;
}
mDragging = false;
mActivePointerId = INVALID_POINTER_ID;
ValueAnimator animator = ObjectAnimator.ofPropertyValuesHolder(mTopCard,
PropertyValuesHolder.ofFloat("translationX", 0),
PropertyValuesHolder.ofFloat("translationY", 0),
PropertyValuesHolder.ofFloat("rotation", (float) Math.toDegrees(mRandom.nextGaussian() * DISORDERED_MAX_ROTATION_RADIANS)),
PropertyValuesHolder.ofFloat("pivotX", mTopCard.getWidth() / 2.f),
PropertyValuesHolder.ofFloat("pivotY", mTopCard.getHeight() / 2.f)
).setDuration(250);
animator.setInterpolator(new AccelerateInterpolator());
animator.addListener(new AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
animating = true;
}
@Override
public void onAnimationRepeat(Animator animation) {
animating = true;
}
@Override
public void onAnimationEnd(Animator animation) {
animating = false;
dislikeImage.setVisibility(View.INVISIBLE);
likeImage.setVisibility(View.INVISIBLE);
((Profile) getAdapter().getItem(0)).getOnCardDimissedListener().cancelCard();
}
@Override
public void onAnimationCancel(Animator animation) {
animating = false;
}
});
animator.start();
break;
case MotionEvent.ACTION_POINTER_UP:
pointerIndex = event.getActionIndex();
final int pointerId = event.getPointerId(pointerIndex);
if (pointerId == mActivePointerId) {
final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
mLastTouchX = event.getX(newPointerIndex);
mLastTouchY = event.getY(newPointerIndex);
mActivePointerId = event.getPointerId(newPointerIndex);
}
break;
}
return true;
}
private void getHitRect(View v, Rect rect) {
rect.left = (int) (v.getLeft() + v.getTranslationX());
rect.top = (int) (v.getTop() + v.getTranslationY());
rect.right = rect.left + v.getWidth();
rect.bottom = rect.top + v.getHeight();
}
public boolean isAnimating()
{
return animating;
}
public Profile getCurrentCard() {
if(index + 1 > getAdapter().getCount())
return null;
Profile profile = (Profile) getAdapter().getItem(index);
if (index + 1 == getAdapter().getCount())
profile.setLast(true);
return profile;
}
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
try {
Log.e("CARD CONTAINER","MTOPCARD =====================+++++++++ "+mTopCard);
if (mTopCard == null) {
return false;
}
if (mGestureDetector.onTouchEvent(event)) {
return true;
}
final int pointerIndex;
final float x, y;
final float dx, dy;
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
getHitRect(mTopCard,childRect);
Profile Profile = (Profile) getAdapter().getItem(0);
if (Profile.getOnClickListener() != null) {
Profile.getOnClickListener().OnClickListener();
}
pointerIndex = event.getActionIndex();
x = event.getX(pointerIndex);
y = event.getY(pointerIndex);
if (!childRect.contains((int) x, (int) y)) {
return false;
}
mLastTouchX = x;
mLastTouchY = y;
mActivePointerId = event.getPointerId(pointerIndex);
break;
case MotionEvent.ACTION_MOVE:
pointerIndex = event.findPointerIndex(mActivePointerId);
x = event.getX(pointerIndex);
y = event.getY(pointerIndex);
if (Math.abs(x - mLastTouchX) > mTouchSlop || Math.abs(y - mLastTouchY) > mTouchSlop) {
float[] points = new float[]{x - mTopCard.getLeft(), y - mTopCard.getTop()};
mTopCard.getMatrix().invert(mMatrix);
mMatrix.mapPoints(points);
mTopCard.setPivotX(points[0]);
mTopCard.setPivotY(points[1]);
return true;
}
}
return false;
} catch (Exception e) {
// TODO Auto-generated catch block
return super.onInterceptTouchEvent(event);
}
}
@Override
public View getSelectedView() {
throw new UnsupportedOperationException();
}
@Override
public void setSelection(int position) {
throw new UnsupportedOperationException();
}
public int getGravity() {
return mGravity;
}
public void setGravity(int gravity) {
mGravity = gravity;
}
public static class LayoutParams extends ViewGroup.LayoutParams {
int viewType;
public LayoutParams(Context c, AttributeSet attrs) {
super(c, attrs);
}
public LayoutParams(int width, int height) {
super(width, height);
}
public LayoutParams(ViewGroup.LayoutParams source) {
super(source);
}
public LayoutParams(int w, int h, int viewType) {
super(w, h);
this.viewType = viewType;
}
}
private class GestureListener extends SimpleOnGestureListener {
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
final View topCard = mTopCard;
float dx = e2.getX() - e1.getX();
if (Math.abs(dx) > mTouchSlop &&
Math.abs(velocityX) > Math.abs(velocityY) &&
Math.abs(velocityX) > mFlingSlop * 3) {
float targetX = topCard.getX();
float targetY = topCard.getY();
long duration = 0;
boundsRect.set(0 - topCard.getWidth() - 100, 0 - topCard.getHeight() - 100, getWidth() + 100, getHeight() + 100);
while (boundsRect.contains((int) targetX, (int) targetY)) {
targetX += velocityX / 10;
targetY += velocityY / 10;
duration += 100;
}
duration = Math.min(400, duration);
cardModel = (Profile) getAdapter().getItem(0);
if (cardModel.getOnCardDimissedListener() != null) {
if ( targetX > 0 ) {
{
if(MyUser.getInstance((Activity)context).getVip().equals("1") || (Float.valueOf((getCurrentCard()).getScore())>MyGenericApp.getInstance((Activity)context).getMinScoreMatch()))
{
mTopCard = getChildAt(getChildCount() - 2);
if (mTopCard != null)
mTopCard.setLayerType(LAYER_TYPE_HARDWARE, null);
cardModel.getOnCardDimissedListener().onLike();
}
else
{
cardModel.getOnCardDimissedListener().forcedToDislike();
return super.onFling(e1, e2, velocityX, velocityY);
}
}
} else {
mTopCard = getChildAt(getChildCount() - 2);
if (mTopCard != null)
mTopCard.setLayerType(LAYER_TYPE_HARDWARE, null);
cardModel.getOnCardDimissedListener().onDislike();
}
index++;
}
animating = true;
topCard.animate()
.setDuration(duration)
.alpha(.75f)
.setInterpolator(new LinearInterpolator())
.x(targetX)
.y(targetY)
.rotation(Math.copySign(45, velocityX))
.setListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
removeViewInLayout(topCard);
ensureFull();
if(getCurrentCard()!=null)
cardModel.getOnCardDimissedListener().initialiseCard();
animating = false;
}
@Override
public void onAnimationCancel(Animator animation) {
onAnimationEnd(animation);
}
});
return true;
} else
return false;
}
}
public void dislike(){
final View topCard = mTopCard;
View likeImage = mTopCard.findViewById(R.id.like_text_image);
View dislikeImage = mTopCard.findViewById(R.id.dislike_text_image);
dislikeImage.setVisibility(View.VISIBLE);
likeImage.setVisibility(View.INVISIBLE);
mTopCard = getChildAt(getChildCount() - 2);
Profile cardModel = (Profile)getAdapter().getItem(0);
if(mTopCard != null)
mTopCard.setLayerType(LAYER_TYPE_HARDWARE, null);
animating = true;
topCard.animate()
.setDuration(400)
.alpha(.75f)
.setInterpolator(new LinearInterpolator())
.x(-GlobalFunctions.getScreenWidth(context))
.y(topCard.getY())
.rotation(-45)
.setListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
removeViewInLayout(topCard);
ensureFull();
animating = false;
}
@Override
public void onAnimationCancel(Animator animation) {
onAnimationEnd(animation);
}
});
if(cardModel.getOnCardDimissedListener() != null){
cardModel.getOnCardDimissedListener().onDislike();
}
index++;
if(index < getAdapter().getCount())
((Profile)getAdapter().getItem(0)).getOnCardDimissedListener().initialiseCard();
}
public void like(){
final View topCard = mTopCard;
View likeImage = mTopCard.findViewById(R.id.like_text_image);
View dislikeImage = mTopCard.findViewById(R.id.dislike_text_image);
likeImage.setVisibility(View.VISIBLE);
dislikeImage.setVisibility(View.INVISIBLE);
mTopCard = getChildAt(getChildCount() - 2);
Profile cardModel = (Profile)getAdapter().getItem(0);
if(mTopCard != null)
mTopCard.setLayerType(LAYER_TYPE_HARDWARE, null);
animating = true;
topCard.animate()
.setDuration(400)
.alpha(.75f)
.setInterpolator(new LinearInterpolator())
.x(GlobalFunctions.getScreenWidth(context))
.y(topCard.getY())
.rotation(45)
.setListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
removeViewInLayout(topCard);
ensureFull();
animating = false;
}
@Override
public void onAnimationCancel(Animator animation) {
onAnimationEnd(animation);
}
});
if(cardModel.getOnCardDimissedListener() != null){
cardModel.getOnCardDimissedListener().onLike();
}
index++;
if(index < getAdapter().getCount())
((Profile)getAdapter().getItem(0)).getOnCardDimissedListener().initialiseCard();
}
公共类CardContainer扩展AdapterView{
公共静态final int无效\u指针\u ID=-1;
private int mActivePointerId=无效的\u指针\u ID;
私有静态最终双无序_最大_旋转_弧度=Math.PI/64;
私有int MNOfCards=-1;
语境;
private final DataSetObserver mDataSetObserver=新DataSetObserver(){
@凌驾
更改后的公共无效(){
super.onChanged();
clearStack();
ensureFull();
}
@凌驾
未验证的公共无效(){
super.onInvalidated();
clearStack();
}
};
私有最终随机mRandom=新随机();
private final Rect boundsRect=new Rect();
private final Rect childRect=new Rect();
私有最终矩阵mMatrix=新矩阵();
//TODO:根据设备速度动态确定最大值
private int mmaxvible=2;
私人手势检测器mGestureDetector;
私家车;
私人取向;
私有列表适配器;
私有浮动mLastTouchX;
私密的浮躁和敏感;
私有视图mTopCard;
姆图什洛普私人酒店;
私人内部经理;
私有内部mNextAdapterPosition;
私有布尔分布;
私有布尔动画;
整数指数;
剖面模型;
公共CardContainer(上下文){
超级(上下文);
this.context=上下文;
setOrientation(定向。无序);
setGravity(Gravity.TOP);
init();
动画=假;
}
公共CardContainer(上下文、属性集属性){
超级(上下文,attrs);
this.context=上下文;
initFromXml(attrs);
init();
}
公共CardContainer(上下文上下文、属性集属性、int-defStyle){
超级(上下文、属性、定义样式);
this.context=上下文;
initFromXml(attrs);
init();
}
私有void init(){
ViewConfiguration ViewConfiguration=ViewConfiguration
.get(getContext());
mFlingSlop=viewConfiguration.getScaledMinimumFlingVelocity();
mTouchSlop=viewConfiguration.getScaledTouchSlop();
mGestureDetector=新的GestureDetector(getContext(),
新的手势监听器());
}
私有void initFromXml(AttributeSet attr){
TypedArray a=getContext()。获取样式数据属性(属性,
R.styleable.CardContainer);
setGravity(a.getInteger(R.styleable.CardContainer_android_gravity,
重力(上),;
int方向=a
.getInteger(R.styleable.CardContainer_方向,1);
setOrientation(Orientation.fromIndex(Orientation));
指数=0;
a、 回收();
}
@凌驾
公共ListAdapter getAdapter(){
返回多电平适配器;
}
@凌驾
public void setAdapter(ListAdapter适配器){
指数=0;
if(mListAdapter!=null)
mListAdapter.unregisterDataSetObserver(mDataSetObserver);
clearStack();
mTopCard=null;
mListAdapter=适配器;
mNextAdapterPosition=0;
adapter.registerDataSetObserver(mDataSetObserver);
ensureFull();
Log.e(“GETCHILD卡继续”,“getChildAt(getChildCount()-1)==============”+getChildAt(getChildCount()-1));
Log.e(“GETCHILD卡继续”,“getChildCount()=========================”+getChildCount());
如果(getChildCount()!=0){
mTopCard=getChildAt(getChildCount()-1);
mTopCard.setLayerType(层类型硬件,空);
}
mNumberOfCards=getAdapter().getCount();
requestLayout();
((Profile)adapter.getItem(0)).getOnCardDimissedListener().initialiseCard();
}
私人加油站(){
while(mNextAdapterPosition