在这里,你只需要赋值、粘贴和稍微加一点修改即可。适用于有Android基础的同学,并且又不愿意做重复工作的同学
- 涉及到的点有
- 从字符XML中拿数组
- ListView适配器
- 去除标题栏
- 发送消息到通知栏
- 使用Intent 传递对象
- Spinner控件
- 具体项目的DBHelper
- 具体项目的DB
- 全屏模式
- 圆角按钮实现
- 实现按钮被点击的效果
- 覆写系统方法
- 知晓当前活动
- 活动管理器
- 自定义控件
- 网络监测
- 数据持久化方案
- SQLiteDatabase事务
- 自定义内容提供器
- SurfaceView 的基本框架
1.学习安卓的以前都学过web开发
2.
// 从字符XML中拿数组
String[] apps = getResources().getStringArray(R.array.apps);
3.
// ListView适配器
class ListViewAdapter extends BaseAdapter {
@Override
public int getCount() {
return appList.size();
}
@Override
public App getItem(int position) {
return appList.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if (convertView == null) {
// 获取ListViewItem的布局
convertView = View.inflate(MainActivity.this,R.layout.activity_main_item, null);
holder = new ViewHolder();
// 获取子项中的具体布局
holder.image = (ImageView) convertView.findViewById(R.id.iv_list);
holder.text = (TextView) convertView.findViewById(R.id.tv_list);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
// 设置相关信息
holder.image.setImageResource(appList.get(position).getPicId());
holder.text.setText(appList.get(position).getAppName());
return convertView;
}
class ViewHolder {
private ImageView image;
private TextView text;
}
}
4.去除标题栏
(1)requestWindowFeature(Window.FEATURE_NO_TITLE);
(2)在values文件夹下面的styles.xml文件中添加一个样式:
<style name="notitle">
<item name="android:windowNoTitle">true</item>
</style>
然后在AndroidManifest.xml文件中的<application>标签中添加一个android:theme 属性即可.例如:
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/notitle" >
5.发送消息到通知栏
//启动目标Activity的Intent对象
Intent intent = new Intent(UserActivity.this, Welcome.class);
//pengding: 即将
PendingIntent pendIntent =PendingIntent.getActivity(UserActivity.this, 0, intent, 0);
//实例化通知实例
Notification notif= new Notification(R.drawable.welcome, "Hello,Lady or Gentleman!!Click me!!",System.currentTimeMillis());
notif.defaults=Notification.DEFAULT_SOUND;//声音
//拉开之后显示的信息
notif.setLatestEventInfo(UserActivity.this, "Hello", "Hello,Thank you for using app", pendIntent);
//通知管理器 管理通知
NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
//发送通知
manager.notify(1, notif);
6.使用Intent 传递对象
//传递
Intent intent = new Intent();
intent.setClass(UserActivity.this,UserInfo.class);
Bundle bundle = new Bundle();
bundle.putSerializable("user", user);
intent.putExtras(bundle);
this.startActivity(intent);
7.Spinner控件
//当点击登录时才会获取,所以不用放在选项改变的方法中,不用时刻检测,只需要在点击登录时获取就好
String loc = spLoc.getSelectedItem().toString();
8.具体项目的DBHelper
public class CoolWeatherOpenHelper extends SQLiteOpenHelper {
/** * Province建表语句 */
public static final String CREATE_PROVINCE="create table Province (" +
"id integer primary key autoincrement," +
"province_name text," +
"province_code text)";
/** * City建表语句 */
public static final String CREATE_CITY="create table City (" +
"id integer primary key autoincrement," +
"city_name text," +
"city_code text," +
"province_id integer)";
/** * County建表语句 */
public static final String CREATE_COUNTY="create table County (" +
"id integer primary key autoincrement," +
"county_name text," +
"county_code text," +
"city_id integer)";
public CoolWeatherOpenHelper(Context context, String name,
CursorFactory factory, int version) {
super(context, name, factory, version);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(CREATE_PROVINCE);//创建Province表
db.execSQL(CREATE_CITY);//创建City表
db.execSQL(CREATE_COUNTY);//创建County表
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub
}
}
9.具体项目的DB
public class CoolWeatherDB {
/** * 数据库名 */
public static final String DB_NAME="cool_weather";
/** * 数据库版本 */
public static final int VERSION=1;
private static CoolWeatherDB coolWeatherDB;//采用单例模式
private SQLiteDatabase db;
/** * 将构造方法私有化 */
private CoolWeatherDB(Context context){
CoolWeatherOpenHelper dbHelper = new CoolWeatherOpenHelper(context, DB_NAME, null, VERSION);
db = dbHelper.getWritableDatabase();
}
/** * 获取CoolWeatherDB的实例 */
public synchronized static CoolWeatherDB getInstance(Context context){
if(coolWeatherDB == null){
coolWeatherDB = new CoolWeatherDB(context);
}
return coolWeatherDB;
}
/** * 将Province实例存储到数据库 */
public void saveProvince(Province province){
if(province != null){
ContentValues values = new ContentValues();
values.put("province_name", province.getProvinceName());
values.put("province_code", province.getProvinceCode());
db.insert("Province", null, values);
}
}
/** * 从数据库读取全国所有的省份信息 */
public List<Province> loadProvinces(){
List<Province> list = new ArrayList<Province>();
Cursor cursor =db.query("Province", null, null, null, null, null, null);
if(cursor.moveToFirst()){
do{
Province province = new Province();
province.setId(cursor.getInt(cursor.getColumnIndex("id")));
province.setProvinceName(cursor.getString(cursor.getColumnIndex("province_name")));
province.setProvinceCode(cursor.getString(cursor.getColumnIndex("province_code")));
list.add(province);
}while(cursor.moveToNext());
if(cursor != null){
cursor.close();
}
}
if(cursor != null){
cursor.close();
}
return list;
}
}
10.全屏模式(但是标题栏还在,标题栏可去)
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
11.圆角按钮实现:
首先写一个XML,专门处理按钮图形的,比如叫做shape.xml,就先放在drawable文件夹下面吧.
shape.xml:
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
<!-- 填充的颜色 -->
<solid android:color="#FFFFFF" />
<!-- 设置按钮的四个角为弧形 -->
<!-- android:radius 弧形的半径 -->
<corners android:radius="5dip" />
<!-- padding:Button里面的文字与Button边界的间隔 -->
<padding android:left="10dp" android:top="10dp" android:right="10dp" android:bottom="10dp" />
</shape>
接下来,在布局文件中引用就OK 了.
<Button ....... android:background="@drawable/shape" />
12.实现按钮被点击的效果
首先写btn_selector.xml文件
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="false" android:drawable="@drawable/coolweather"/>
<item android:state_pressed="true" android:drawable="@drawable/fiftyfour_backgroun"/>
</selector>
在布局文件中.
<Button ....... android:background="@drawable/btn_selector" />
13.如果在覆写系统方法的时候,报这个错误:
08-25 10:36:28.234: E/AndroidRuntime(5066):java.lang.RuntimeException:Unable to resume activity {com.example.androidvideoplay/com.example.androidvideoplay.MainActivity}: android.app.SuperNotCalledException: Activity {com.example.androidvideoplay/com.example.androidvideoplay.MainActivity} did not call through to super.onResume()
原因在红色字体,已经很清楚的告诉你了,你没有调用系统的super.相应的方法
14.当SurfaceView所在的Activity离开了前台之后,SurfaceView会被摧毁,当Activity有重新回到前台时,SurfaceView会被重新创建,创建是在onResume()方法之后
15.知晓当前是哪一个活动,让此活动成为其他活动的父类
/** * 技巧:知晓当前是哪一个活动,让此活动成为其他活动的父类 FirstActivity extends BaseActivity 、FirstActivity extends BaseActivity ...... */
public class BaseActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.i("BaseActivity",getClass().getSimpleName());
setContentView(R.layout.activity_base);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_base, menu);
return true;
}
}
16.
/** *类描述: 活动管理器 */
public class ActivityCollector {
public static List<Activity> activities = new ArrayList<Activity>();
public static void addActivity(Activity activity){
activities.add(activity);
}
public static void removeActivity(Activity activity){
activities.remove(activity);
}
public static void finishAll(){
for(Activity activity : activities){
if(!activity.isFinishing()){
activity.finish();
}
}
}
}
17.创建自定义控件
/** * * 类描述:自定义的标题控件 */
public class TitleLayout extends LinearLayout {
public TitleLayout(Context context, AttributeSet attrs) {
super(context, attrs);
// 动态加载布局文件
LayoutInflater.from(context).inflate(R.layout.title, this);
// 设定按钮监听事件
findViewById(R.id.title_back).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
//结束当前的Activity
((Activity) getContext()).finish();
}
});
findViewById(R.id.title_edit).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
//在自定义控件里面错误的写法:Toast.makeText(this, "编辑按钮", Toast.LENGTH_LONG).show();
Toast.makeText(getContext(), "编辑按钮", Toast.LENGTH_LONG).show();
}
});
}
}
18.监测网络是否可用
ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
if(networkInfo != null && networkInfo.isAvailable()){
Toast.makeText(context, "网络可用", Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(context, "网络不可用", Toast.LENGTH_SHORT).show();
}
需要在配置文件当中加入相应的权限:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
19.数据持久化方案
a)使用文件
i.将数据存储到文件中
String fileName = "usefile.txt";
String content = "我是要存储的字符串";
try {
FileOutputStream fos = openFileOutput(fileName,
Context.MODE_PRIVATE);
fos.write(content.getBytes());
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
ii.从文件中读取数据
String content = null;
try {
String fileName = "usefile.txt";
FileInputStream fis = openFileInput(fileName);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len = 0;
while ((len = fis.read(buffer)) != -1) {
baos.write(buffer, 0, len);
}
content = baos.toString();
Toast.makeText(MainActivity.this, content, Toast.LENGTH_LONG).show();
fis.close();
baos.close();
} catch (Exception e) {
e.printStackTrace();
}
b) SharedPreferences存储
i.获取 SharedPreferences 对象的三种方式
1).Context的getSharedPreferences();
2).Activity的getPreferences();
3).PreferenceManager 的 getDefaultSharedPreferences();
Demo:
存数据:
SharedPreferences sharedPreferences = getSharedPreferences("data",MODE_PRIVATE);
Editor edit = sharedPreferences.edit();
edit.putString("name", "杨润康");
edit.putInt("age", 20);
edit.commit();
读取数据:
SharedPreferences sharedPreferences = getSharedPreferences("data",MODE_PRIVATE);
String name = sharedPreferences.getString("name", "null");
int age = sharedPreferences.getInt("age", 0);
Toast.makeText(MainActivity.this, name+age, Toast.LENGTH_LONG).show();
20.SQLiteDatabase使用事务[简单点,就是加三行事务的代码,其余的都一样]
SQLiteDatabase db = databaseHelper.getReadableDatabase();
db.beginTransaction();//开启事务
try {
db.delete("Book", null, null);//第一个操作
/*if(true){//模拟故障,手动抛出异常
throw new NullPointerException();
}*/
ContentValues values = new ContentValues();
values.put("author", "blatran");
values.put("price", "300");
values.put("pages", "199");
values.put("name", "yangrunkangtran");
db.insert("Book", null, values);//第二个操作
db.setTransactionSuccessful();//事务已经执行成功
} catch (Exception e) {
e.printStackTrace();
}finally{
db.endTransaction();//结束事务
}
21.完整的自定义内容提供器
/** * 类描述:自定义的内容提供者 */
public class MyProvider extends ContentProvider {
public static final int TABLE1_DIR = 0;
public static final int TABLE1_ITEM = 1;
public static final int TABLE2_DIR = 2;
public static final int TABLE2_ITEM = 3;
public static UriMatcher uriMatcher;
static {
uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
uriMatcher.addURI("com.android_3200_contentresolver.provider",
"table1", TABLE1_DIR);
uriMatcher.addURI("com.android_3200_contentresolver.provider",
"table1/#", TABLE1_ITEM);
uriMatcher.addURI("com.android_3200_contentresolver.provider",
"table2", TABLE2_DIR);
uriMatcher.addURI("com.android_3200_contentresolver.provider",
"table2/#", TABLE2_ITEM);
}
@Override
public boolean onCreate() {
return false;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
switch (uriMatcher.match(uri)) {
case TABLE1_DIR:
//查询table1表中的所有数据
break;
case TABLE1_ITEM:
//查询table1表中的单条数据
break;
case TABLE2_DIR:
//查询table2表中的所有数据
break;
case TABLE2_ITEM:
//查询table2表中的单条数据
break;
default:
break;
}
return null;
}
@Override
public String getType(Uri uri) {
switch (uriMatcher.match(uri)) {
case TABLE1_DIR:
//查询table1表中的所有数据
return "vnd.android.cursor.dir/vnd.com.android_3200_contentresolver.provider.table1";
case TABLE1_ITEM:
//查询table1表中的单条数据
return "vnd.android.cursor.item/vnd.com.android_3200_contentresolver.provider.table1";
case TABLE2_DIR:
//查询table2表中的所有数据
return "vnd.android.cursor.dir/vnd.com.android_3200_contentresolver.provider.table2";
case TABLE2_ITEM:
//查询table2表中的单条数据
return "vnd.android.cursor.item/vnd.com.android_3200_contentresolver.provider.table2";
default:
break;
}
return null;
}
@Override
public Uri insert(Uri uri, ContentValues values) {
return null;
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
return 0;
}
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
return 0;
}
}
内容提供器的具体案例
public class DatabaseProvider extends ContentProvider {
public static final int BOOK_DIR = 0;
public static final int BOOK_ITEM = 1;
public static final int CATEGORY_DIR = 2;
public static final int CATEGORY_ITEM = 3;
private static final String AUTHORITY = "com.android_3100_androidpersistence.provider";
public static UriMatcher uriMatcher;
private MyDatabaseHelper dbHelper;
static {
uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
uriMatcher.addURI(AUTHORITY, "bool", BOOK_DIR);
uriMatcher.addURI(AUTHORITY, "book/#", BOOK_ITEM);
uriMatcher.addURI(AUTHORITY, "category", CATEGORY_DIR);
uriMatcher.addURI(AUTHORITY, "category/#", CATEGORY_ITEM);
}
@Override
public boolean onCreate() {
dbHelper = new MyDatabaseHelper(getContext(), "BookStore.db", null, 2);
return true;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
// 查询数据
SQLiteDatabase db = dbHelper.getReadableDatabase();
Cursor query = null;
switch (uriMatcher.match(uri)) {
case BOOK_DIR:
query = db.query("Book", null, null, null, null, null, null);
break;
case BOOK_ITEM:
String bookId = uri.getPathSegments().get(1);
query = db.query("Book", null, "id=?", new String[] { bookId },null, null, sortOrder);
break;
case CATEGORY_DIR:
query = db.query("Category", null, null, null, null, null, null);
break;
case CATEGORY_ITEM:
String categoryId = uri.getPathSegments().get(1);
query = db.query("Category", null, "id=?",new String[] { categoryId }, null, null, sortOrder);
break;
default:
break;
}
return query;
}
@Override
public String getType(Uri uri) {
switch (uriMatcher.match(uri)) {
case BOOK_DIR:
return "vnd.android.cursor.dir/vnd."+AUTHORITY+".book";
case BOOK_ITEM:
return "vnd.android.cursor.item/vnd."+AUTHORITY+".book";
case CATEGORY_DIR:
return "vnd.android.cursor.dir/vnd."+AUTHORITY+".category";
case CATEGORY_ITEM:
return "vnd.android.cursor.item/vnd."+AUTHORITY+".category";
}
return null;
}
@Override
public Uri insert(Uri uri, ContentValues values) {
// 添加数据
SQLiteDatabase db = dbHelper.getReadableDatabase();
Uri uriReturn = null;
switch (uriMatcher.match(uri)) {
case BOOK_DIR:
case BOOK_ITEM:
long newBookId = db.insert("Book", null, values);
uriReturn = Uri.parse("content://" + AUTHORITY + "/book/"+ newBookId);
break;
case CATEGORY_DIR:
case CATEGORY_ITEM:
long newCategoryId = db.insert("Category", null, values);
uriReturn = Uri.parse("content://" + AUTHORITY + "/category/"+ newCategoryId);
break;
default:
break;
}
return uriReturn;
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
// 删除数据
SQLiteDatabase db = dbHelper.getReadableDatabase();
int deleteRows = 0;
switch (uriMatcher.match(uri)) {
case BOOK_DIR:
deleteRows = db.delete("Book", selection, selectionArgs);
break;
case BOOK_ITEM:
String bookId = uri.getPathSegments().get(1);
deleteRows = db.delete("Book", "id=?",new String[] { bookId });
break;
case CATEGORY_DIR:
deleteRows = db.delete("Category", selection, selectionArgs);
break;
case CATEGORY_ITEM:
String categoryId = uri.getPathSegments().get(1);
deleteRows = db.delete("Category", "id=?",new String[] { categoryId });
break;
default:
break;
}
return deleteRows;
}
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
// 更新数据
SQLiteDatabase db = dbHelper.getReadableDatabase();
int updateRows = 0;
switch (uriMatcher.match(uri)) {
case BOOK_DIR:
updateRows = db.update("Book", values, selection, selectionArgs);
break;
case BOOK_ITEM:
String bookId = uri.getPathSegments().get(1);
updateRows = db.update("Book", values, "id=?",new String[] { bookId });
break;
case CATEGORY_DIR:
updateRows = db.update("Category", values, selection, selectionArgs);
break;
case CATEGORY_ITEM:
String categoryId = uri.getPathSegments().get(1);
updateRows = db.update("Category", values, "id=?",new String[] { categoryId });
break;
default:
break;
}
return updateRows;
}
}
最后不要忘了在AndroidManifest.xml中进行注册:
<!-- 注册自定义的内容提供器 --> <provider android:name="com.android_3100_androidpersistence.DatabaseProvider" android:authorities="com.android_3100_androidpersistence.provider" android:exported="true" ></provider>
注意:使用内容提供器时,如果报null异常,一般就是uri 和你定义的地址没有匹配上
22.SurfaceView 的基本框架 SurfaceView可以做许多交互性的东西,比如说最常见的互动游戏
package com.luckPan;
import android.content.Context;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.view.SurfaceHolder;
import android.view.SurfaceHolder.Callback;
import android.view.SurfaceView;
public class SurfaceViewTemplate extends SurfaceView implements Callback, Runnable {
private SurfaceHolder mHolder;
private Canvas mCanvas;
/** * 用于线程绘制 */
private Thread t;
/** * 线程的控制开关 */
private boolean isRunning;
public SurfaceViewTemplate(Context context) {
this(context,null);
}
public SurfaceViewTemplate(Context context, AttributeSet attrs) {
super(context, attrs);
mHolder = getHolder();
mHolder.addCallback(this);
//设置可获得焦点
setFocusable(true);
setFocusableInTouchMode(true);
//设置常量
setKeepScreenOn(true);
}
public void surfaceCreated(SurfaceHolder holder) {
isRunning = true;
t = new Thread(this);
t.start();
}
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
}
public void surfaceDestroyed(SurfaceHolder holder) {
isRunning = false;
}
public void run() {
while(isRunning){
draw();
}
}
private void draw() {
try {
mCanvas = mHolder.lockCanvas();
if (mCanvas != null) {
//draw something
}
} catch (Exception e) {
}finally{
if (mCanvas != null) {
mHolder.unlockCanvasAndPost(mCanvas);
}
}
}
}