import android.content.Context; import android.graphics.Bitmap; import android.graphics.Color; import android.os.Build; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.util.AttributeSet; import android.view.Gravity; import android.view.ViewGroup; import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.LinearLayout; import com.example.administrator.asapplication.ImageVariable; import com.example.administrator.asapplication.R; import java.util.List; public class ImageBarnnerFramLayout extends FrameLayout implements ImageBarnnerViewGroup.ImageBarnnerViewGroupLisnner, ImageBarnnerViewGroup.ImageBarnnerLister{ private ImageBarnnerViewGroup imageBarnnerViewGroup; private LinearLayout linearLayout; private FramLayoutLisenner lisenner; public FramLayoutLisenner getLisenner() { return lisenner; } public void setLisenner(FramLayoutLisenner lisenner) { this.lisenner = lisenner; } public ImageBarnnerFramLayout(@NonNull Context context) { super(context); initImageBarnnerViewGroup(); initDotLinearLayout(); } public ImageBarnnerFramLayout(@NonNull Context context, @Nullable AttributeSet attrs) { super(context, attrs); initImageBarnnerViewGroup(); initDotLinearLayout(); } public ImageBarnnerFramLayout(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); initImageBarnnerViewGroup(); initDotLinearLayout(); } public void addBitmap( List<Bitmap> list){ for(int i = 0; i<list.size(); i++){ Bitmap bitmap = list.get(i); addBitmapToImageBarnnerViewGroup(bitmap); addDotToLinearlayout(); } } private void addBitmapToImageBarnnerViewGroup(Bitmap bitmap){ ImageView iv = new ImageView(getContext()); iv.setScaleType(ImageView.ScaleType.CENTER_CROP); iv.setLayoutParams(new ViewGroup.LayoutParams(ImageVariable.WIDTH, ImageVariable.HEIGHT/4)); iv.setImageBitmap(bitmap); imageBarnnerViewGroup.addView(iv); } private void addDotToLinearlayout(){ ImageView iv = new ImageView(getContext()); LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT); lp.setMargins(5, 5, 5 ,5); iv.setLayoutParams(lp); iv.setImageResource(R.drawable.dot_normal); linearLayout.addView(iv); } /** * 初始化我们自定义图片轮播图功能的核心类 */ private void initImageBarnnerViewGroup(){ imageBarnnerViewGroup = new ImageBarnnerViewGroup(getContext()); FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT); imageBarnnerViewGroup.setLayoutParams(lp); imageBarnnerViewGroup.setBarnnerViewGroupLisnner(this);//这里就是将Lisnner,传递给Framlayout imageBarnnerViewGroup.setLister(this); addView(imageBarnnerViewGroup); } /** * 初始化我们的底部圆点布局 */ private void initDotLinearLayout(){ linearLayout = new LinearLayout(getContext()); FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, 40); linearLayout.setLayoutParams(lp); linearLayout.setOrientation(LinearLayout.HORIZONTAL);//方向:水平居中 linearLayout.setGravity(Gravity.CENTER); linearLayout.setBackgroundColor(Color.RED);//轮播图圆点的背景颜色 addView(linearLayout); FrameLayout.LayoutParams layoutParams = (LayoutParams) linearLayout.getLayoutParams(); layoutParams.gravity = Gravity.BOTTOM; linearLayout.setLayoutParams(layoutParams); //版本3.0以后的用setAlpha(),3.0之前用的是setAlpha(),但是调用者不同 if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB){ linearLayout.setAlpha(0.5f); }else{ linearLayout.getBackground().setAlpha(100); } } @Override public void selectImage(int index) { int count = linearLayout.getChildCount(); for (int i = 0; i < count; i++) { ImageView iv = (ImageView) linearLayout.getChildAt(i); if( i == index){ iv.setImageResource(R.drawable.dot_select); }else { iv.setImageResource(R.drawable.dot_normal); } } } @Override public void clickImageIndex(int pos){ lisenner.clickImageIndex(pos); } public interface FramLayoutLisenner{ void clickImageIndex(int pos); } }
对于OOM,其实最重要的是注意不要Memory Leak。而Memory Leak是会有多个方面会引起的,比如Drawable, RemoteViews, Receiver, Cursor,InputStream, MediaPlayer等,此外,如果使用JNI也会因为C或C++的代码导致Memory Leak。
除了Memory Leak,大数据量的操作也会导致OOM,比如之前其他回答提到的Bitmap,还有ListAdapter,如果在getView时处理不当,也很容易导致OOM,所以在ListAdapter时应该尽量使用convertView。
最后,可以用android.os.StrictMode以及Eclipse的MAT工具来进行OOM和Memory Leak的检测。
作者:Billy Cui
链接:https://www.zhihu.com/question/19772290/answer/13325580
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
可以去下面的链接看看,里面说了多种滑动冲突的解决方案
http://www.jianshu.com/p/87a41b8c0dd0
可以实现无限轮播
1、针对内存溢出问题,不应该传递Bitmap,直接传递R.drawable.xxx到里面即可;
2、拦截问题,修改如下:
定义一个TouchSlop
mTouchSlop = ViewConfiguration.get(context).getScaledPagingTouchSlop();
@Override public boolean onInterceptTouchEvent(MotionEvent ev) { switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: stopAuto(); isClick = true; mStartX = (int) ev.getX(); mPreviousX = mStartX; break; case MotionEvent.ACTION_MOVE: int diff = (int) Math.abs(ev.getX() - mStartX); mPreviousX = (int) ev.getX(); //横向滑动距离超过slop值才拦截; if (diff > mTouchSlop) { isClick = false; return true; } break; case MotionEvent.ACTION_UP: if (isClick) { listener.onClick(mIndex); } startAuto(); break; } return super.onInterceptTouchEvent(ev); }
//拦截后处理该事件; @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_MOVE: int moveX = (int) event.getX(); int distance = moveX - mPreviousX; scrollBy(-distance, 0); mPreviousX = moveX; break; case MotionEvent.ACTION_UP: int scrollX = getScrollX(); mIndex = (scrollX + mChildWidth / 2) / mChildWidth; if (mIndex < 0) { mIndex = 0; } else if (mIndex > mChildCount - 1) { mIndex = mChildCount - 1; } int dx=mIndex * mChildWidth - scrollX; mScroller.startScroll(scrollX, 0,dx , 0); invalidate(); startAuto(); changedListener.onImageChanged(mIndex); break; } return super.onTouchEvent(event); }
使用这个方法有一个注意点,就是每一个ImageView一定要加一个Clickable.
protected void onLayout(boolean changed, int l, int t, int r, int b) { if (changed) { int leftMargin = 0; for (int i = 0; i < mChildCount; i++) { View child = getChildAt(i); child.layout(leftMargin, 0, leftMargin + mChildWidth, mChildHeight); leftMargin += mChildWidth; //加一个Clickable. child.setClickable(true); } } }