未来年薪百万的安卓工程师
慕粉3499826
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);
}
}
慕田峪7532397
对于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
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
EmbraceU
可以去下面的链接看看,里面说了多种滑动冲突的解决方案
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);
}
}
}