2011年5月8日 星期日

Custom list view

被交代修改個AP,功能是列出所有sensor還必須有包含還得到的Data,簡單的listactivity是無法應付需要的。

網路上找到一篇文章可以參考Custom ListView,但我還是碰到一些帶解決的問題。

  1. 我希望list是不特定長度,可隨系統讀到的變更。
  2. 按照Custom ListView做出來,sensor又如何動態更新。
接下來直接看程式碼,首先需要兩個layout
首先是sensor_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
  <ListView android:id="@+id/android:list"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"/>
</LinearLayout>

再來是sensor_list.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="fill_parent"
     android:layout_height="wrap_content"
     android:orientation="vertical">

     <TextView android:id="@+id/sensorname"
         android:textSize="14px"
         android:textStyle="bold"
         android:layout_width="fill_parent"
         android:layout_height="wrap_content"/>
     <TextView android:id="@+id/f1"
         android:textSize="14px"
         android:layout_width="fill_parent"
         android:layout_height="wrap_content"/>
     <TextView android:id="@+id/f2"
         android:textSize="14px"
         android:layout_width="fill_parent"
         android:layout_height="wrap_content"/>
     <TextView android:id="@+id/f3"
         android:textSize="14px"
         android:layout_width="fill_parent"
         android:layout_height="wrap_content"/>

 </LinearLayout>

最後是Java的部份

package otaku_thinking.demo;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import android.app.ListActivity;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.widget.SimpleAdapter;

public class sensorlistactivity extends ListActivity implements SensorEventListener {
    static final String LOG_TAG = "ATestingSensors";
    private SensorManager sensorManager;
    private List<Sensor> sensors;
    private ArrayList<HashMap<String, String>> list = new  ArrayList<HashMap<String, String>>();  
    final static String fields[] = { "f1", "f2", "f3"};
    private SimpleAdapter sensorAdapter = null;

    private void AddItem()
    {

        for( int i = 0 ; i < sensors.size() ; ++i )
        {   
            HashMap<String, String> map = new  HashMap<String, String>();  
            map.put( "sensorname" , sensors.get(i).getName());         
            map.put( fields[0] , "0");  
            map.put( fields[1] , "0");
            map.put( fields[2] , "0");
            list.add(map);  
        }
    }
    
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.sensor_main);
         sensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);
         sensors = sensorManager.getSensorList(Sensor.TYPE_ALL);
         AddItem();
         sensorAdapter = new  SimpleAdapter( this ,  
                 list,
                 R.layout.sensor_list,                              
                 new  String[] { "sensorname" , "f1" , "f2" , "f3" },                     
                 new  int [] {R.id.sensorname,R.id.f1,R.id.f2,R.id.f3}
                 );     
         
         setListAdapter(sensorAdapter);            
    }

    protected void onStart() {
        super.onStart();
        for( int i = 0 ; i < sensors.size() ; ++i )
        {  
            sensorManager.registerListener( 
                    this, 
                    sensors.get(i),
                    SensorManager.SENSOR_DELAY_UI );
        }
    }
    
    protected void onStop() {
        super.onStop();
        if( sensorManager != null )
            sensorManager.unregisterListener( this );
    }
    
    // SensorEventListener
    public void onAccuracyChanged (Sensor sensor, int accuracy) {
    }

    public void onSensorChanged(SensorEvent sensorEvent) {

        HashMap<String, String> map = null;
        for( int i = 0 ; i < sensors.size() ; ++i )
        {   
            
            if(sensors.get(i).getName().endsWith(sensorEvent.sensor.getName()))
            {
                map = list.get(i);  
            }
        }
        
        StringBuilder b = new StringBuilder();
        for( int i = 0 ; i < sensorEvent.values.length ; ++i ) {
            if( i > 0 )
                b.append( " , " );
            b.append( Float.toString( sensorEvent.values[i] ) );
        }

        int count = sensorEvent.values.length < fields.length ?
                    sensorEvent.values.length :
                    fields.length;
        for( int i = 0 ; i < count ; ++i ) {
            map.put(fields[i] , Float.toString( sensorEvent.values[i] ) );  
        }
        sensorAdapter.notifyDataSetChanged();
    }
}

而我的第一個問題在AddItem()得到解決

private void AddItem()
    {

            for( int i = 0 ; i < sensors.size() ; ++i )
            {   
                HashMap<String, String> map = new  HashMap<String, String>();  
                map.put( "sensorname" , sensors.get(i).getName());         
                map.put( fields[0] , "0");  
                map.put( fields[1] , "0");
                map.put( fields[2] , "0");
                list.add(map);  
            }
    }

宣告個HashMap並陸續餵資料,之後加進list裡面,之後new SimpleAdapter將data與listactivity關聯建立起來。

sensorAdapter = new  SimpleAdapter( this ,  
                 list,
                 R.layout.sensor_list,                              
                 new  String[] { "sensorname" , "f1" , "f2" , "f3" },                     
                 new  int [] {R.id.sensorname,R.id.f1,R.id.f2,R.id.f3}
                 );

而第二個問題在onSensorChanged()得到解決
public void onSensorChanged(SensorEvent sensorEvent) {

        HashMap<String, String> map = null;
        for( int i = 0 ; i < sensors.size() ; ++i )
        {   
            
            if(sensors.get(i).getName().endsWith(sensorEvent.sensor.getName()))
            {
                map = list.get(i);  
            }
        }
        
        StringBuilder b = new StringBuilder();
        for( int i = 0 ; i < sensorEvent.values.length ; ++i ) {
            if( i > 0 )
                b.append( " , " );
            b.append( Float.toString( sensorEvent.values[i] ) );
        }

        int count = sensorEvent.values.length < fields.length ?
                    sensorEvent.values.length :
                    fields.length;
        for( int i = 0 ; i < count ; ++i ) {
            map.put(fields[i] , Float.toString( sensorEvent.values[i] ) );  
        }
        sensorAdapter.notifyDataSetChanged();
    }
透過list.get(i)得到原始data,並加以修改之後告知sensorAdapter update date (sensorAdapter.notifyDataSetChanged())。


沒有留言:

張貼留言