Android开发之代码优化

来源:互联网 发布:淘宝美宝莲旗舰店假货 编辑:程序博客网 时间:2024/05/22 02:21

从最早第一天上C语言课的时候,我老师就跟我们讲过,别啥玩意都写在main函数里面,把里面的东西分离出来封装一下,然后在main函数中调用。当时写的是算法题,其实只要能得出正确答案,并不用太过于在意代码的机构。可是如果写Android项目的话,动辄上万行代码,全写在四大组件里,其实没有任何问题,项目一样能跑的起来,不过那样的代码可维护性,拓展性,可读性都会非常烂。以前写过一个制作表情包的App,先开始项目的主要代码全部压在了Activity里面,也没怎么在意,后来觉得这项目写的太烂,又把代码重构了一遍,虽然项目的功能完全没有变,可是代码的逻辑和结构变得更加清晰,也更易于维护拓展了。因为项目的代码量比较大,而这篇博文主要想讲解的是代码优化,所以写了个简化版的作为讲解,去掉了原来项目里大部分的功能,只留些许的功能讲解其中数据和视图的分离。

这里写图片描述

左边的ListView单机可以添加图片进表情包,右边的ListView是可以选取某个图片进行操作,长按则删除,中间的是个控制面板,可以通过触碰对图片进行位置移动//原项目没这么丑,这是简化版的,各位看官担待。

先贴原先的代码 ,也就是没进行过优化前所有代码都积压在Activity的代码

item_layout.xml

<RelativeLayout    xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="70dp">    <ImageView        android:id="@+id/type_image"        android:layout_centerVertical="true"        android:layout_width="50dp"        android:layout_height="50dp" /></RelativeLayout>

activity_main.xml

<LinearLayout    xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical"    tools:context="com.example.cjm.simplefight.MainActivity">    <ImageView        android:id="@+id/fight_img"        android:layout_width="match_parent"        android:layout_height="0dp"        android:layout_weight="1"/>    <LinearLayout        android:layout_width="match_parent"        android:layout_height="0dp"        android:layout_weight="1"        android:orientation="horizontal">        <ListView            android:id="@+id/ori_list"            android:layout_width="0dp"            android:layout_height="match_parent"            android:layout_weight="1"/>        <com.example.cjm.simplefight.MoveView            android:id="@+id/move_view"            android:layout_width="0dp"            android:layout_height="match_parent"            android:layout_weight="1"/>        <ListView            android:id="@+id/img_list"            android:layout_width="0dp"            android:layout_height="match_parent"            android:layout_weight="1"/>    </LinearLayout></LinearLayout>
public class ViewItem {    private Bitmap bitmap;    private int x;    private int y;    public Bitmap getBitmap() {        return bitmap;    }    public void setBitmap(Bitmap bitmap) {        this.bitmap = bitmap;    }    public int getX() {        return x;    }    public void setX(int x) {        this.x = x;    }    public int getY() {        return y;    }    public void setY(int y) {        this.y = y;    }}
public class MoveView extends View {    /*    * 该控件为控制台中操控元素上下左右移动的控件    * 提供了一个接口    * 回调了手指在该控件的移动情况    * 这样就可以使元素进行相应的移动    * */    private int color=getResources().getColor(R.color.mycolor);    private float startX;    private float startY;    public interface MoveViewListener{        void move(float staX,float staY,float stoX,float stoY);    }    private MoveViewListener moveViewListener;    public void setMoveViewListener(MoveViewListener moveViewListener) {        this.moveViewListener = moveViewListener;    }    public MoveView(Context context) {        this(context, null);    }    public MoveView(Context context, AttributeSet attrs) {        this(context, attrs, 0);    }    public MoveView(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);    }    @Override    public boolean onTouchEvent(MotionEvent event) {        switch (event.getAction()){            case MotionEvent.ACTION_DOWN:                startX=event.getX();                startY=event.getY();                break;            case MotionEvent.ACTION_MOVE:                float stopX=event.getX();                float stopY=event.getY();                moveViewListener.move(startX,startY,stopX,stopY);                startX=stopX;                startY=stopY;                break;            case MotionEvent.ACTION_UP:                break;        }        return true;    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);    }    @Override    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {        super.onLayout(changed, left, top, right, bottom);    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        canvas.drawColor(color);    }}
public class ImgAdapter extends BaseAdapter{    private List<ViewItem> itemList;    private LayoutInflater inflater;    public ImgAdapter(Context context,List<ViewItem> itemList){        this.itemList=itemList;        inflater=LayoutInflater.from(context);    }    @Override    public int getCount() {        return itemList.size();    }    @Override    public Object getItem(int position) {        return itemList.get(position);    }    @Override    public long getItemId(int position) {        return position;    }    @Override    public View getView(int position, View convertView, ViewGroup parent) {        AdapterHolder holder=null;        ViewItem viewItem=itemList.get(position);        if(convertView==null){            holder=new AdapterHolder();            //当元素类别为图片时,加载图片的布局            convertView=inflater.inflate(R.layout.item_layout,parent,false);            holder.type_image=(ImageView)convertView.findViewById(R.id.type_image);            convertView.setTag(holder);        }else{            holder=(AdapterHolder)convertView.getTag();        }        holder.type_image.setImageBitmap(viewItem.getBitmap());        return convertView;    }    private final class AdapterHolder{        private ImageView type_image;    }}
public class MainActivity extends Activity {    private int poi=-1;    private Bitmap picture;    private ImageView imageView;    private ListView ori_list;    private ListView img_list;    private List<ViewItem> oriItems;    private List<ViewItem> imgItems;    private ImgAdapter oriAdapter;    private ImgAdapter imgAdapter;    private MoveView moveView;    private int res[]={R.drawable.a10,R.drawable.a11,R.drawable.a12,R.drawable.a13,R.drawable.a14,R.drawable.a15};    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        InitData();        InitView();        InitListener();    }    private void InitData(){        oriItems=new ArrayList<ViewItem>();        imgItems=new ArrayList<ViewItem>();        for(int i:res){            ViewItem item=new ViewItem();            item.setBitmap(BitmapFactory.decodeResource(getResources(),i));            oriItems.add(item);        }    }    private void InitView(){        oriAdapter=new ImgAdapter(this,oriItems);        imgAdapter=new ImgAdapter(this,imgItems);        imageView=(ImageView)findViewById(R.id.fight_img);        ori_list=(ListView)findViewById(R.id.ori_list);        img_list=(ListView)findViewById(R.id.img_list);        moveView=(MoveView)findViewById(R.id.move_view);        ori_list.setAdapter(oriAdapter);        img_list.setAdapter(imgAdapter);    }    private void InitListener(){        ori_list.setOnItemClickListener(new AdapterView.OnItemClickListener() {            @Override            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {                ViewItem item=oriItems.get(position);                ViewItem newItem=new ViewItem();                newItem.setX(30);                newItem.setY(30);                newItem.setBitmap(item.getBitmap());                imgItems.add(item);                imgAdapter.notifyDataSetChanged();                draw();            }        });        img_list.setOnItemClickListener(new AdapterView.OnItemClickListener() {            @Override            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {                poi=position;                draw();            }        });        moveView.setMoveViewListener(new MoveView.MoveViewListener() {            @Override            public void move(float staX, float staY, float stoX, float stoY) {                Amove(staX,staY,stoX,stoY);                draw();            }        });    }    private void draw(){        picture = Bitmap.createBitmap(imageView.getWidth(), imageView.getHeight(), Bitmap.Config.ARGB_8888);        Canvas canvas=new Canvas(picture);        canvas.drawColor(Color.WHITE);        for(ViewItem item:imgItems) {            canvas.drawBitmap(item.getBitmap(), item.getX(), item.getY(), null);        }        if(poi!=-1){            ViewItem item=imgItems.get(poi);            Paint pc = new Paint();            pc.setStrokeWidth(5);            pc.setStyle(Paint.Style.STROKE);            canvas.drawRect(item.getX(), item.getY(), item.getX() + item.getBitmap().getWidth(),                    item.getY() + item.getBitmap().getHeight(), pc);        }        imageView.setImageBitmap(picture);    }    private void Amove(float staX, float staY, float stoX, float stoY){        int moveX = (int) (stoX - staX);        int moveY = (int) (stoY - staY);        ViewItem item = imgItems.get(poi);        item.setX(item.getX() + moveX);        item.setY(item.getY() + moveY);    }}

项目代码就这么多,主要的逻辑都在Activity里面了,非常不好维护,现在从MainActivity方法中把数据抽离出来封装成ViewController类,去控制数据,然后提供相应的public函数供MainActivity去调用,一方面使数据相对独立自制,MainActivity的代码也会变得简洁很多,只需要去生成相应的Data,View,Listener函数就可以了
下面是把MainActivity抽离出来的两个类

public class ViewController {    private List<ViewItem> itemList;    private Bitmap picture=null;    public ViewController(){        itemList=new ArrayList<ViewItem>();    }    public List<ViewItem> getList(){        return itemList;    }    public void addItem(ViewItem item){        itemList.add(item);    }    public void draw(ImageView imageView,int poi){        picture = Bitmap.createBitmap(imageView.getWidth(), imageView.getHeight(), Bitmap.Config.ARGB_8888);        Canvas canvas=new Canvas(picture);        canvas.drawColor(Color.WHITE);        for(ViewItem item:itemList) {            canvas.drawBitmap(item.getBitmap(), item.getX(), item.getY(), null);        }        if(poi!=-1){            ViewItem item=itemList.get(poi);            Paint pc = new Paint();            pc.setStrokeWidth(5);            pc.setStyle(Paint.Style.STROKE);            canvas.drawRect(item.getX(), item.getY(), item.getX() + item.getBitmap().getWidth(),                    item.getY() + item.getBitmap().getHeight(), pc);        }        imageView.setImageBitmap(picture);    }    public void move(int poi,float staX, float staY, float stoX, float stoY){        int moveX = (int) (stoX - staX);        int moveY = (int) (stoY - staY);        ViewItem item = itemList.get(poi);        item.setX(item.getX() + moveX);        item.setY(item.getY() + moveY);    }}
public class MainActivity extends Activity {    private int poi=-1;    private ImageView imageView;    private ListView ori_list;    private ListView img_list;    private List<ViewItem> oriItems;    private ImgAdapter oriAdapter;    private ImgAdapter imgAdapter;    private ViewController viewController;    private MoveView moveView;    private int res[]={R.drawable.a10,R.drawable.a11,R.drawable.a12,R.drawable.a13,R.drawable.a14,R.drawable.a15};    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        InitData();        InitView();        InitListener();    }    private void InitData(){        viewController=new ViewController();        oriItems=new ArrayList<ViewItem>();        for(int i:res){            ViewItem item=new ViewItem();            item.setBitmap(BitmapFactory.decodeResource(getResources(),i));            oriItems.add(item);        }    }    private void InitView(){        oriAdapter=new ImgAdapter(this,oriItems);        imgAdapter=new ImgAdapter(this,viewController.getList());        imageView=(ImageView)findViewById(R.id.fight_img);        ori_list=(ListView)findViewById(R.id.ori_list);        img_list=(ListView)findViewById(R.id.img_list);        moveView=(MoveView)findViewById(R.id.move_view);        ori_list.setAdapter(oriAdapter);        img_list.setAdapter(imgAdapter);    }    private void InitListener(){        ori_list.setOnItemClickListener(new AdapterView.OnItemClickListener() {            @Override            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {                ViewItem item=oriItems.get(position);                ViewItem newItem=new ViewItem();                newItem.setX(30);                newItem.setY(30);                newItem.setBitmap(item.getBitmap());                viewController.addItem(item);                imgAdapter.notifyDataSetChanged();                viewController.draw(imageView,poi);            }        });        img_list.setOnItemClickListener(new AdapterView.OnItemClickListener() {            @Override            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {                poi=position;                viewController.draw(imageView,poi);            }        });        moveView.setMoveViewListener(new MoveView.MoveViewListener() {            @Override            public void move(float staX, float staY, float stoX, float stoY) {                viewController.move(poi,staX,staY,stoX,stoY);                viewController.draw(imageView,poi);            }        });    }}

或许是因为这个项目其实也很小,看不出这种写法的优越之处,当一个Activity的代码量庞大的时候,会明显感觉到一个整合Activity中所用到的数据的类的好处。

1 0
原创粉丝点击