Tuesday, October 28, 2014

Android: UI design

Fragment in Activity(xml in xml)
方法一(不推荐): 类似于MyStatsFragment,MyStatsFragment初始化xml2,然后取代要内置的占位的那一行xml1

方法二:<include>重用xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout android:id="@+id/drawer_layout" android:layout_width="fill_parent" android:layout_height="fill_parent"
  xmlns:android="http://schemas.android.com/apk/res/android">
    <FrameLayout android:id="@+id/content_frame" android:layout_width="fill_parent" android:layout_height="fill_parent" />
    <include
        android:id="@+id/left_drawer"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        layout="@layout/fragment_left_menu"
        />
</android.support.v4.widget.DrawerLayout>

fragment_left_menu为xml2的名字
http://developer.android.com/training/improving-layouts/reusing-layouts.html
ListView
ArrayAdatper and simpleAdapter
http://www.vogella.com/tutorials/AndroidListView/article.html

custom click:
 adapter = new SimpleAdapter(getActivity(), list,
   R.layout.pageview_timeline_cardview, from, to)
{
   @Override
   public View getView(int position, View convertView,
           ViewGroup parent) {
       View view =super.getView(position, convertView, parent);
       final int pos = position;
       RelativeLayout rlayout=(RelativeLayout) view.findViewById(R.id.rgm_card);
       rlayout.setOnClickListener(new OnClickListener()
        {

           @Override
           public void onClick(View v)
           {
            Log.d(TAG, pos);
           }
       });

       return view;
   }
};

Action bar

@Override
public boolean onOptionsItemSelected(MenuItem item) 
{    
   switch (item.getItemId()) 
   {        
      case android.R.id.home:            
         Intent intent = new Intent(this, ActOnThisActivity.class);            
         intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 
         startActivity(intent);            
         return true;        
      default:            
         return super.onOptionsItemSelected(item);    
   }
}
ActionBar bar = getActionBar();
bar.setDisplayHomeAsUpEnabled(true);
http://www.informit.com/articles/article.aspx?p=1743642&seqNum=4

Action bar with right hand side:
可能需要android-support-v7-appcompat.jar
<menu xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:yourapp="http://schemas.android.com/apk/res-auto" >
    <item android:id="@+id/action_search"
          android:icon="@drawable/map_icon_default"
          android:title="Checkin"
          android:showAsAction="ifRoom" />
</menu>

//action bar right hand side
@Override
public boolean onCreateOptionsMenu(Menu menu) {
   // Inflate the menu items for use in the action bar
   MenuInflater inflater = getMenuInflater();
   inflater.inflate(R.menu.pathlist_activity_actions, menu);
   return super.onCreateOptionsMenu(menu);
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle presses on the action bar items
    switch (item.getItemId()) {
        case R.id.action_search:
            openSearch();
            return true;
        case R.id.action_compose:
            composeMessage();
            return true;
        default:
            return super.onOptionsItemSelected(item);
    }
}


Navigation Drawer

http://blog.csdn.net/xyz_lmn/article/details/12523895
https://developer.android.com/design/patterns/navigation-drawer.html
https://www.codeofaninja.com/2014/02/android-navigation-drawer-example.html



Custom theme:

Custom theme

http://stackoverflow.com/questions/11675500/sherlock-actionbar-styles


Dialog:

     RecordDialogFragment dialog = new RecordDialogFragment();
    dialog.show(getFragmentManager(), "NoticeDialogFragment");

DialogFragment

Monday, October 27, 2014

Android: Http post文件到php server



http://androidcodeforbeginners.blogspot.in/2013/05/send-xml-data-from-android-to-php-server.html

Sunday, October 26, 2014

Android: dynamic list view


这个layout.xml是固定的具体可以看一下贴
http://blog.csdn.net/flowingflying/article/details/6256739

Friday, October 24, 2014

Android: 组件间通信(activity, fragment, service)


service和activity通信

Activity:
 Intent serviceIntent = new Intent(this,ListenLocationService.class);
   serviceIntent.putExtra("From", "Main");
   startService(serviceIntent);
//and get the parameter in onStart method of your service class

service:
@Override
public void onStart(Intent intent, int startId) {
    super.onStart(intent, startId);
     Bundle extras = intent.getExtras();
if(extras == null)
    Log.d("Service","null");
else
{
    Log.d("Service","not null");
    String from = (String) extras.get("From");
    if(from.equalsIgnoreCase("Main"))
        StartListenLocation();
}

如果putExtra输入是Int, 在bundle就要用getInt 类型一定要match 否则报错!


Fragment和Activity通信:

Fragment->Activity:
In your fragment you can call getActivity(). This will give you access to the activity that created the fragment. From there you can obviously call any sort of accessor methods that are in the activity.

MainFragmentActivity parent;
parent.setCurrentLatLng(new LatLng(location.getLatitude(),location.getLongitude()));

setCurrentLatLng是activity的方法



Activity和Activity通信:

基本类型:
    Activity 1:
                Intent intent = new Intent(getActivity() ,PathDetailActivity.class);
                int pathid=pos;
                intent.putExtra("pathid", pathid);
                getActivity().startActivity(intent);
    Activity 2
            Intent intent = getIntent();
   int pathid = intent.getIntExtra("pathid", 0);

复合类型:

    Activity 1:
             Intent intent = new Intent(getActivity() ,PathDetailActivity.class);
                      Bundle data = new Bundle(); data.putParcelable("stats", stats.get(pos));                    
                      intent.putExtra("bundle",data); getActivity().
                      startActivity(intent);
    Activity 2
             Intent intent = getIntent();
   Bundle bundle = intent.getParcelableExtra("bundle");
    Stats stats = bundle.getParcelable("stats");

这里Stats必须是实现Parcelable
http://techdroid.kbeanie.com/2010/06/parcelable-how-to-do-that-in-android.html

    Activity 1:
      Bundle data = new Bundle();
    Intent intent = new Intent(MainFragmentActivity.this,CheckinActivity.class);
    //intent.putExtra("pathid", pathid);
    data.putParcelable("currentPoint", this.curPoint);
    data.putInt("pathid", pathid);
    intent.putExtra("bundle",data);
    startActivity(intent);

利用intent通信,数据可以是基本类型(pathid is int),也可以是复合甚至自定义类型,可以用bundle封装 curPoint是LatLng类型.

Activity 2(onCreate):
            Intent intent = getIntent();
   //pathid = intent.getIntExtra("pathid", 0);
   Bundle bundle = intent.getParcelableExtra("bundle");
   curPoint = bundle.getParcelable("currentPoint");
   pathid = bundle.getInt("pathid");

当然也可以用data.putSerializable("person",p)来封装,具体见android讲义P240

Wednesday, October 8, 2014

Eclipse安装C++


下载CDT更新
http://download.eclipse.org/tools/cdt/releases/juno
ref:
http://jingyan.baidu.com/article/380abd0a5888211d90192cd6.html

此时Eclipse内部可以build C++了,但是好似不能运行

安装MinGW,把bin目录加入环境变量path,make**.ext那个改成make.exe,打开cmd测试make,这时可以进入eclipse生成的CTest.exe运行,即可出现想要的结果

或者C++ online: http://cpp.sh/
python online: http://repl.it/languages/Python

Saturday, October 4, 2014

Android之ConentProvider Uri详解

假设我们的contentProvider名叫PathRecordingService, 这里在AndroidManifest.xml中可以看到
          <provider
        android:name="edu.njit.trackmypath.db.DataProvider"
        android:authorities="edu.njit.trackmypath"
        android:exported="true"/>

在DAO类,定义Uri CONTENT_URI: content://edu.njit.trackmypath/pathpoints, 这是要监听的Uri对应是table pathpoints,当然Uri和table也可以不一致。还有定义
public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.njit.pathpoint";
public static final String CONTENT_ITEMTYPE = "vnd.android.cursor.item/vnd.njit.pathpoint";


在ContentProvider中,定义Uri
   public static final String AUTHORITY = "edu.njit.trackmypath";
    private static final int PATHPOINTS_TABLE_ID = 1;

    private static final UriMatcher uriMatcher;
    static {
            uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
            uriMatcher.addURI(AUTHORITY, PathPointsTable.TABLE_NAME,                    
                             PATHPOINTS_TABLE_ID);
    }

public String getType(Uri uri) {

switch (uriMatcher.match(uri))
{
       case PATHPOINTS_TABLE_ID:
        return PathPointsTable.CONTENT_TYPE;
       default:
           throw new IllegalArgumentException("Error Uri: " + uri);
              }
}
这里PATHPOINTS_TABLE_ID只是一个Uri的整数代号,所以在这里CONTENT_URI就返回PathPointsTable.CONTENT_TYPE对应DAO中是vnd.android.cursor.dir。vnd.android.cursor.dir和vnd.android.cursor.item是Android中两种Uri解释方式,dir是全表变化监听,而item是监听某Row的变化。如果要监听某row,如下:
uriMatcher.addURI(AUTHORITY, “pathpoints/#”,2)
返回应选CONTENT_ITEMTYPE, #代表数字
这样就可以监听某行变化,如content://edu.njit.trackmypath/pathpoints/28

而监听变化的实现是在ContentProvider中
@Override
public Uri insert(Uri uri, ContentValues values) {
long id = db.insert(PathPointsTable.TABLE_NAME, PathPointsTable._ID, values);
if(id < 0)
throw new SQLiteException("Unable to insert " + values + " for " + uri);

Uri newUri = ContentUris.withAppendedId(uri, id);
Log.d(TAG, "new URI:"+newUri);
                resolver.notifyChange(newUri, null);  

                return newUri;
}
newUri是content://edu.njit.trackmypath/pathpoints/28,notifyChange就会通知observer
context.getContentResolver().registerContentObserver(uri, true, observer);

Ref:
http://blog.csdn.net/luoshengyang/article/details/6950440
http://blog.csdn.net/luoshengyang/article/details/6985171

Android之Observer pattern观察者模式ContentObserver

观察者模式是一个observer观察着subject变化从而做相应动作的模式。程序可以注册多个观察者去监视subject的变化。
用例场合
1. 资源耗费较少的情况下,可以由一个变化触发不同类的行为.
2. 多个观察者。

下面例子是一个关于跟踪用户而在map上画出其轨迹的Android app. 这个app首先利用GPS service服务把坐标写入sqlite里面(GPS服务有监听范围,比如移动50米才写入sqlite). 所以Subject就是sqlite里面path table,任意这个table的变化通过uri都会通知观察者---Google map地图类,从而在地图上画上相应的坐标。另一个observer是统计轨迹数据,比如距离、速度等。

核心类PathsTableObserver是继承ContentObserver重写相应函数onChange
主类Activity中调用getContentResolver().registerContentObserver(uri, false, PathsTableObserver);

uri为监听链接。

//subject类由Anroid框架实现

//观察者类
private class PathsTableObserver extends ContentObserver
{
        @Override
public void onChange(boolean selfChange, Uri newUri)
       {
             observersManager.nodifyNewLocation(location);
       }
}

public class ObserversManager {

      public void start()
     {
   DatabaseObserver dbObserver = new DatabaseObserver(this);
         context.getContentResolver().registerContentObserver(PathPointsTable.DB_URI, true, dbObserver.getPathsTableObserver());

     }
}

还有一个例子:

实现原理只要将观察者(ParkingLot)对象/对象数组作为Subject(ParkingSpot)的一个属性,然后调用观察者的函数即可
abstract class ParkingSpot {
MyParkingLot lot;

public void unpark(){

lot.updateStatus();
}
}

Ref:
http://blog.csdn.net/qinjuning/article/details/7047607

Thursday, October 2, 2014

Java线程池和Android Handler

Handler:
http://blog.csdn.net/wanglong0537/article/details/6304239

thread pool:
http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2013/0304/958.html
http://blog.sina.com.cn/s/blog_a5f093b401015npp.html
http://blog.csdn.net/jadyer/article/details/7338080

Wednesday, October 1, 2014

SQLite简介

SQLite是Android中的持久层

JAVA代码中用SQLiteOpenHelper调用
super(context, DATABASE_NAME, null, DATABASE_VERSION);
可以创建数据库Database_name取trackmypath.db

再执行SQL命令db.execSQL(PathPointsTable.CREATE_TABLE);
PathPointsTable.CREATE_TABLE是创建表代码如:"create table (Name)"
以上部分似乎是题外话,不用java,用sql命令也可以达到相同功能

假设我们已经创建了一个叫trackmypath.db, android程序默认路径是
//data/data/<Your-Application-Package-Name>/databases/<your-database-name>
所以我们的例子是/data/data/edu.njit.trackmypath/databases/trackmypath.db

Andriod SDK提供SQLite工具
android-sdk\platform-tools\进入目录后

$ adb -s emulator-5554 shell 进入该emulator
# sqlite3 “/data/data/edu.njit.trackmypath/databases/trackmypath.db”(加引号)

这是会出现# sqlite>开头的启示符,我们就可以写SQL命令了,记住所有语句一定要以分号结尾,比如
select count(*) from pathpoints;

sqlite3还有一些内置命令
.tables 列出所有table
.schema 列出所有table定义
.exit 退出

Ref:
http://www.cnblogs.com/hicjiajia/archive/2011/01/25/1944581.html
http://developer.android.com/tools/help/sqlite3.html