2015年3月17日 星期二

SQLite

複寫SQLiteOpenHelper
public class DBHelper extends SQLiteOpenHelper {
    private final static String DATABASE_NAME = "price_app.db";
    private final static int DATABASE_VERSION = 1;

    public DBHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        //需要建立的table SQL語法
        String createTable = "CREATE TABLE IF NOT EXISTS GeoStatus " +
                "(_ID INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL," +
                " CountiesUpdateTime nvarchar(50) ,MRTUpdateTime nvarchar(50) )";
        db.execSQL(createTable);
    }


    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        //oldVersion=舊的資料庫版本;newVersion=新的資料庫版本
        //修改DATABASE_VERSION來改變
        //資料庫版本異動 ex 修改某table欄位時
         if (newVersion > oldVersion) {
            db.beginTransaction();//建立交易
            boolean success = false;//判斷參數

            //由之前不用的版本,可做不同的動作    
            switch (oldVersion) {
                case 1:
                    db.execSQL("ALTER TABLE GeoStatus ADD COLUMN reminder integer DEFAULT 0");
                    success = true;
                    break;
            }

            if (success) {
                //正確交易才成功
                db.setTransactionSuccessful();
            }
            db.endTransaction();
        } else {
            onCreate(db);
        }

}

Insert / Update / Delete
        DBHelper dbHelper = new DBHelper(conText);
        SQLiteDatabase db = dbHelper.getWritableDatabase();

        //insert
        ContentValues cv = new ContentValues();
        //cv.put(column ,value);
        cv.put("city_code", "0000");
        cv.put("district_code", "1");
        //db.insert(table name ,nullColumnHack ,ContentValues values)
        db.insert("District", null, cv);


        //update
        ContentValues cv = new ContentValues();
        //cv.put(column ,value);
        cv.put("city_name", "新北市");
        //db.update(table name ,ContentValues values, whereClause ,whereArgs[])
        db.update("City", cv, "city_code = '0000'", null);
  
        
        //delete
        //db.update(table name , whereClause ,whereArgs[])
        db.delete("City", "city_code = '0000'", null);


        db.close();


Query
        DBHelper dbHelper = new DBHelper(conText);
        SQLiteDatabase db = dbHelper.getReadableDatabase();

        String SQL = "select city_code ,city_name from City order by sort asc";
        Cursor cursor = db.rawQuery(SQL, null);
        while (cursor.moveToNext()) {
            String cityCode = cursor.getString(0); //第一個欄位
            //或是 cursor.getString(cursor.getColumnIndex("city_code"));
        }
        cursor.close();
        db.close();

2015年3月16日 星期一

API POST傳值

List nvps = new ArrayList();
//new BasicNameValuePair(key, value)
nvps.add(new BasicNameValuePair("source", "1"));
nvps.add(new BasicNameValuePair("pinstr", "10"));
nvps.add(new BasicNameValuePair("pinend", "50"));

HttpClient mHttpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);
httpPost.setEntity(new UrlEncodedFormEntity(nvps, "UTF-8"));
HttpResponse mHttpResponse = mHttpClient.execute(httpPost);
      

2015年3月12日 星期四

Layout 背景框線

在drawable新增 xml檔案
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <!--
    shape的類型含有:  
    1.rectangle   長方形、矩形
    2.oval   橢圓形、卵形
    3.line   線
    4.ring   環形
    -->
    <!-- 圓角,Layout佈局圓角幅度設定值 -->
    <corners android:radius="5dip" />
    <!-- 外框,框線粗細,框線顏色 -->
    <stroke
        android:width="1.0dip"
        android:color="@color/background_gray" />
</shape>

layout設定background
        
<LinearLayout
    android:id="@+id/layout_xxx"
    android:background="@drawable/shape_rectangle_gray"
    android:gravity="center_horizontal"
    android:orientation="vertical"
    android:padding="2dp">
</LinearLayout>

客製化 map icon




















因來源不同及價錢同需客制可變icon
先用layout設計











View map_icon = ((LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate({layout id}, null);
//圖示價錢
TextView txt_price = (TextView) map_icon.findViewById(R.id.txt_price);
txt_price.setText("958");

//加到地圖
mMap.addMarker(new MarkerOptions()
    .position(latLng)
    .snippet(gPrice.getID())
    .icon(BitmapDescriptorFactory.fromBitmap(createDrawableFromView(MapActivity.this, map_icon))));

將view繪製成圖
    // Convert a view to bitmap
    public static Bitmap createDrawableFromView(Context context, View view) {
        DisplayMetrics displayMetrics = new DisplayMetrics();
        ((Activity) context).getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
        view.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
        view.measure(displayMetrics.widthPixels, displayMetrics.heightPixels);
        view.layout(0, 0, displayMetrics.widthPixels, displayMetrics.heightPixels);
        view.buildDrawingCache();
        Bitmap bitmap = Bitmap.createBitmap(view.getMeasuredWidth(), view.getMeasuredHeight(), Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);
        view.draw(canvas);

        return bitmap;
    }

2015年3月11日 星期三

共用Layout

相同畫面例如天/地 (like UserControl)












要共用的Layout 獨自存成xml檔案
需要用的Layout 再<include>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="50dp"
    android:orientation="vertical">
    .
    .
    .
    <include
        android:id="@+id/include_top"
        layout="@layout/include_top" />
    .
    .
    .
    .
</LinearLayout>

使用 incude裡的控件
        
        //找到被include的layout
        View top = findViewById(R.id.include_top);
        //include layout上的控件
        top.findViewById(R.id.btn_XXX).setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
              // do something
            }
        });

自訂義Adapter 繼承BaseAdapter

較複雜的 List Item  如下
















須自行定義Adapter
public class PriceAdapter extends BaseAdapter {

    private LayoutInflater myInflater;
    private ArrayList<PriceObject> mItems = new ArrayList<PriceObject>();

    public PriceAdapter(Context context, ArrayList<PriceObject> items) {
        myInflater = LayoutInflater.from(context);
        mItems = items;
    }

    public void addItem(ArrayList<PriceObject> items) {
        for (int i = 0; i < items.size(); i++) {
            mItems.add(items.get(i));
        }
        this.notifyDataSetChanged();
    }

    public int getCount() {
        return mItems.size();
    }

    public Object getItem(int position) {
        return mItems.get(position);
    }

    public long getItemId(int position) {
        return position;
    }

    public View getView(int position, View convertView, ViewGroup parent) {
        if (convertView == null) {
            convertView = myInflater.inflate({list item layout id}, null);
        }
         //do something
        TextView text = (TextView) convertView.findViewById({list item裡的物件ID});
        text.setText(mItems.get(position).getXXXX());

        return convertView;
    }
}

自行整理好的mPriceObject 設定給 PriceAdapter
adapter再給ListView
PriceAdapter priceAdapter = new PriceAdapter(this, mPriceObject);
lvPriceList.setAdapter(priceAdapter);

ListView的OnItemClickListener失效

ListView 使用自訂義Adapter(繼承BaseAdapter)
導致OnItemClickListener失效
在 ListItem Layout 最外層加上
android:descendantFocusability="blocksDescendants"
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:descendantFocusability="blocksDescendants"
    android:orientation="vertical"
    android:padding="10dp">
</LinearLayout>