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中所用到的数据的类的好处。
- Android开发之代码优化
- Android开发之性能优化(Java代码优化)
- Android优化之代码优化
- 项目开发之代码优化
- 项目开发之代码优化
- [Android] Android开发优化之——从代码角度进行优化
- [Android] Android开发优化之——从代码角度进行优化
- [Android] Android开发优化之——从代码角度进行优化
- [Android] Android开发优化之——从代码角度进行优化
- [Android] Android开发优化之——从代码角度进行优化
- 【Android】 Android开发优化之——从代码角度进行优化
- [Android] Android开发优化之——从代码角度进行优化
- Android] Android开发优化之——从代码角度进行优化
- [Android] Android开发优化之——从代码角度进行优化
- [Android] Android开发优化之——从代码角度进行优化
- Android优化之优化Java代码
- Android性能优化之二 代码优化
- 性能优化之Java(Android)代码优化
- Service 通过 BroadcastReceiver与Activity 进行通信
- Mysql中的commit()语句
- java中的回调机制
- POJ3254 Corn Fields
- 记录:Properties方法演示
- Android开发之代码优化
- 《UNIX环境高级编程》十四高级I/O读书笔记
- Python 之 闭包
- Elasticsearch笔记一之简介与安装
- 别以为真懂Openstack: 虚拟机创建的50个步骤和100个知识点(3)
- 206. Reverse Linked List
- 在javascript中读取php数组
- 131. Palindrome Partitioning
- IntentService介绍