凤凰微课HD Android版 总结

近一个月的时间,前几天把android版的凤凰微课HD版做完了,之前做iPad版的时候没写什么总结,这次因为是自己的第一个android项目,所以想写一些经验。

自己现在对android兴趣不是很浓,并不像对待iOS那样会去搜很多资料来看,android更像是一个扩展,也算是完成任务,不过做的过程中还是学到了不少东西的。


项目架构

用的是MVP(Model-View-Presenter)模式,这个模式是对MVC的细化。下图是MVP模式下的一个示意图



下图是项目中的分包图



其实通过上面的示意图,大家都应该可以知道MVP模式是怎样一个流程了。
View当然就是我们熟悉的Activity,在activity中的所有用户操作也好,所有的数据加载也好,数据交互也好,全部这次的实际操作都由presenter来做,
activity只负责进行页面的展示。
在presenter中很多时候都是需要进行异步操作,下载数据或者是处理数据,在完成了这一系列工作之后要通知activity更新界面或者是做出反馈,
这个时候就通过interface来通知activity啦。
在Presenter中需要存储数据,除了基本类型的数据集合外,更多的是会存储类类型的集合,这些数据模型就在Model中定义。
使用MVP的模式有什么好处呢,我觉得主要是逻辑操作和界面展示分开,在代码结构上显得比较清晰,修改和扩展都比较容易,debug也轻松一些。

记得之前去听一个沙龙讲座的时候,有一个讲师说:“架构就是分文件夹”,虽然听起来很直白,但就我目前的水平来看,确实是这样...就是通过分包,不同的包里面的类做不同的用途。

看回上面的源码分包图,
第一个包放的都是Activity;
api包放的是api地址常量
helpers包放的是一些工具类,http请求、SQLite操作、图片异步加载类等等
models和presenters就是上面的model和presenter啦,最后的views类是放接口的。

下面是mvp模式实际应用的代码片段
//MainActivity.java

import ....;

public class MainActivity extends Activity implements IMainActivity{

	MainActivityPresenter _presenter;
	ArrayList<DataModel> datas;
	.......

	@Override
	protected void onCreate(Bundle savedInstanceState) {

		........

		_presenter = new MainActivityPresenter(this);

		........

		_presenter.loadMainPageData();
	}

	........

	@Override
	protected void manageMainPageData(ArrayList<DataModel> mainPageData) {
		//get the mainPage data
		datas = mainPageData;
		/**
			*do other things with data 
			*eg.refresh the listview
		*/
		listviewAdapter.notifyDataSetChanged();
	}
}


//IMainActivity.java
public interface IMainActivity {
	
	void manageMainPageData(ArrayList<DataModel> mainPageData);
}

//MainActivityPresenter.java
public class MainActivityPresenter {

	IMainActivity _view;
	ArrayList<DataModel> datas;
	.......

	public MainActivityPresenter(IMainActivity view) {
		this._view = view;
	}

	public void loadMainPageData() {
		new MainPageDataDownloadTask().execute(MicroCourseAPI.mainPageData);
	}


	class MainPageDataDownloadTask extends AsyncTask<String,Integer,ArrayList<DataModel>>
	{
		@Override
		protected ArrayList<DataModel> doInBackground(String... params) {
	        
	        //下载、解析、处理数据
	        .......

			return startIndexs;
		}
		
		@Override
		protected void onPostExecute(ArrayList<DataModel> result) {

			//在presenter中保存或对数据进行进一步处理
			..........

			//使用接口通知activity数据准备完毕
			_view.manageMainPageData(result);
		}
}
通过上面的片段,大家应该都可以知道mvp模式的基本使用了,我讲的不是很清楚,有兴趣的朋友戳右边继续了解— —〉 http://magenic.com/Blog/AnMVPPatternforAndroid

其他具体的实现、各种控件的使用没什么好讲的,这次用到一个开源的horizontal listView实现横向的listView操作: DevsmartLib-Android
下载图片使用的是AsyncImageLoader,这个在这篇博客里面已经有介绍: http://blog.csdn.net/kay_sprint/article/details/8778240
其他的listView的使用、Gallery的使用、其他控件、AsyncTask、Handler、HTTP请求等的使用在这里就不再说了,因为都是比较基础的使用而已,并没有怎么自定义。

SQLITE操作

简单说下sqlite的操作,首先要说的是,在代码中频繁出现sql语句,是很不好的一种代码编写习惯,所以对数据库操作的sql语句都要封装起来,不然从整体上和代码的阅读性上来说,都不好。
直接上代码,因为看了代码之后就清晰多了
public class DatabaseHelper extends SQLiteOpenHelper {

	private static final String DATABASE_NAME = "favourVideo.db";  
	private static final int DATABASE_VERSION = 1; 
	
	public DatabaseHelper(Context context) {
		//set CursorFactory to null,use the default value 
		super(context, DATABASE_NAME, null, DATABASE_VERSION);	
	}

	@Override
	public void onCreate(SQLiteDatabase db) {
		//create the table
		........
	}

	@Override
	public void onUpgrade(SQLiteDatabase arg0, int arg1, int arg2) {
		// TODO Auto-generated method stub
		
	}

}

public class DatabaseManager {

	private DatabaseHelper dbHelper;
	private SQLiteDatabase db;
	
	public DatabaseManager(Context context) {
		dbHelper = new DatabaseHelper(context);
		db = dbHelper.getWritableDatabase();
	}
	
	public void add(FavourData favourData) {
		//写insert语句
	}
	
	public void delete(FavourData favourData) {
		//写删除
		db.delete("favourVideo", "SESSIONID = ?", new String[]{favourData.sessionID});
	}
	
	public ArrayList<FavourData> queryAll() {
		//写查找
	}
	
	public void closeDB() {
		db.close();
	}

	//根据自己需要添加方法
}

在操作数据库的使用只要使用DatabaseManager的实例调用相应的方法就可以了,不用再在代码中出现各种突兀的SQL语句。

最后说下android屏幕适配的问题

屏幕适配

现在不管是android还是Windows 8还有现在的iPhone都存在屏幕适配的问题,iPhone并不排除以后会出现更多的分辨率。
android和windows 8的适配基本是使用百分比的形式,在细节部分再微调。

这次的项目,使用的是百分比的适配。

首先,在开发过程中,我使用的是dp作为尺寸单位,在160ppi的屏幕上,1dp=1px,我这次也比较幸运的撞上了使用1280*800的10寸平板,刚好是160ppi
所以计算百分比比较简单,首先是在10寸上面排布好之后,根据每个Layout或者控件在屏幕上的百分比(控件像素大小/屏幕像素大小)
根据这个百分比,在Acticity显示该控件的时候,使用代码设置该控件的大小。

获取屏幕像素的方法
		DisplayMetrics displayMetrics = new DisplayMetrics();
		getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
		ScreenHelper.screenWidth = displayMetrics.widthPixels;
		ScreenHelper.screenHeight = displayMetrics.heightPixels;
		Log.e("dis px","width "+ScreenHelper.screenWidth+" height "+ScreenHelper.screenHeight);



下面是一些适配的代码片段
RelativeLayout rl = (RelativeLayout)findViewById(R.id.main_topbar);
rl.getLayoutParams().height = (int)(ScreenHelper.screenHeight * 0.06f);
rl.invalidate();

........

LinearLayout.LayoutParams params3 = new LinearLayout.LayoutParams(
		LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
params3.setMargins((int) (ScreenHelper.screenWidth * 0.016f),
		(int) (ScreenHelper.screenWidth * 0.036f),
		(int) (ScreenHelper.screenWidth * 0.016f), 0);
recCourseName.setLayoutParams(params3);
recCourseName.setTextSize(fontSize + 3);


LinearLayout.LayoutParams params4 = new LinearLayout.LayoutParams(
		(int) (ScreenHelper.screenWidth * 0.224f + 0.5f),
		LayoutParams.WRAP_CONTENT);
params4.setMargins((int)(ScreenHelper.screenWidth * 0.01f), (int)(ScreenHelper.screenHeight * 0.015f), 0, 0);
ImageView line = (ImageView)findViewById(R.id.courseInfo_line);
line.setLayoutParams(params4);


LayoutParams params2 = (LayoutParams)favourBtn.getLayoutParams();
params2.height = (int)(ScreenHelper.screenHeight * 0.047f + 0.5f);
params2.width = (int)(ScreenHelper.screenWidth * 0.06f + 0.5f);
favourBtn.setLayoutParams(params2);

使用屏幕百分比只是其中一个大步骤,因为android的设备尺寸大小也很多,加上现在很多高ppi设备,仅仅依靠百分比来适配界面是不够的,很多时候还需要根据屏幕的物理尺寸,作为调整的前提。
总之,android的适配问题就是烦人。
  • 5
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值