2012-11-22 152 views
0

我試圖實現一個簡單的Android REST客戶端,並且我在理解如何在我的活動之間傳遞數據時遇到了一些問題。從ListView中選擇項(Json數據)

我有這個ListActivity(我使用Spring REST模板):

public class MainActivity extends ListActivity 
{ 
    protected static final String TAG = MainActivity.class.getSimpleName(); 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     //setContentView(R.layout.activity_main); 
    } 

    @Override 
    protected void onListItemClick(ListView l, View v, int position, long id) { 
     Toast.makeText(this, "You have selected" + position + id , 
       Toast.LENGTH_SHORT).show(); 
    } 

    @Override 
    protected void onStart() { 

     super.onStart(); 
     new DownloadClientesTask().execute(); 
    } 

    private void refreshClientes(List<Cliente> clientes) { 
     if (clientes == null) { 
      return; 
     } 

     ClientesListAdapter adapter = new ClientesListAdapter(this, clientes); 
     setListAdapter(adapter); 
    } 

    private class DownloadClientesTask extends AsyncTask<Void, Void, List<Cliente>> { 

     @Override 
     protected List<Cliente> doInBackground(Void... params) { 
      final String url = "http://192.168.1.119/~henry/api_slim/index.php/customers"; 

      try { 
       // Set the Accept header for "application/json" 
       HttpHeaders requestHeaders = new HttpHeaders(); 
       List<MediaType> acceptableMediaTypes = new ArrayList<MediaType>(); 
       acceptableMediaTypes.add(MediaType.APPLICATION_JSON); 
       requestHeaders.setAccept(acceptableMediaTypes); 

       // Populate the headers in an HttpEntity object to use for the request 
       HttpEntity<?> requestEntity = new HttpEntity<Object>(requestHeaders); 

       // Create a new RestTemplate instance 
       RestTemplate restTemplate = new RestTemplate(); 
       restTemplate.getMessageConverters().add(new MappingJacksonHttpMessageConverter()); 

       // Perform the HTTP GET request 
       ResponseEntity<Cliente[]> responseEntity = restTemplate.exchange(url, HttpMethod.GET, requestEntity, 
         Cliente[].class); 

       // convert the array to a list and return it 
       return Arrays.asList(responseEntity.getBody()); 
      } catch (Exception e) { 
       // TODO Auto-generated catch block 
       Log.e(TAG, e.getMessage(), e); 
      } 

      return null; 

     } 

     @Override 
     protected void onPostExecute(List<Cliente> result) { 

      refreshClientes(result); 
     } 

    } 

} 

,這是我listAdapter:

public class ClientesListAdapter extends BaseAdapter{ 

    private List<Cliente> clientes; 
    private final LayoutInflater layoutInflater; 

    public ClientesListAdapter(Context context, List<Cliente> clientes) { 
     this.clientes = clientes; 
     this.layoutInflater = LayoutInflater.from(context); 
    } 

    @Override 
    public int getCount() { 
     // TODO Auto-generated method stub 
     return this.clientes != null ? clientes.size() : 0; 
    } 

    @Override 
    public Cliente getItem(int position) { 
     return this.clientes.get(position); 
    } 

    @Override 
    public long getItemId(int position) { 
     // TODO Auto-generated method stub 
     return position; 
    } 

    @Override 
    public View getView(int position, View convertView, ViewGroup parent) { 
     if (convertView == null) { 
      convertView = this.layoutInflater.inflate(R.layout.cliente_list_item, parent, false); 
     } 

     Cliente cliente = getItem(position); 
     if (cliente != null) { 
      TextView t = (TextView) convertView.findViewById(R.id.name); 
      t.setText(cliente.getFirstname()); 
     } 

     return convertView; 
    } 

} 

該POJO類的數據的即時得到:

public class Cliente { 
    private Integer id_customer; 
     private String firstname; 
     public Integer getId_customer() { 
     return id_customer; 
    } 
    public void setId_customer(Integer id_customer) { 
     this.id_customer = id_customer; 
    } 
     public String getFirstname() { 
     return firstname; 
    } 
    public void setFirstname(String firstname) { 
     this.firstname = firstname; 
    } 
} 

當我從listView中選擇一個元素,我想顯示有關th的具體細節是另一個活動或片段的元素,但我不知道如何從列表中獲取此元素的customer_id,當我處理響應時,是否必須保存它?我是否需要使用內容提供者或數據庫提供此行爲?我真的很困惑,提前感謝任何幫助!

+0

您是否嘗試過使用「putExtra()」他的意圖?你可能想看看這裏:http://stackoverflow.com/questions/3848148/sending-information-with-intent-putextra和在這裏:http://stackoverflow.com/questions/2736389/how-to-pass -object-from-one-activity-to-another-in-android – Radu

+0

你爲什麼評論setContentView()? – Houcine

+0

嘿@胡希奇沒有具體的原因,我在嘗試一些東西,但它的工作原理是這樣的。此外與setContentView但佈局必須有一個espefic id列表android:id/list – Henry1988

回答

0

有關於如何從一個活動傳遞到另一個數據herepass objects between activities很好的例子。您可能需要先看看這些鏈接上的解決方案。

請看下面的例子,可以讓你在正確的軌道上。

列表適配器類:

public class ClientesListAdapter extends BaseAdapter{ 

    //private members 
    private List<Cliente> clientes; 

    //adapter position - not used for this example 
    public int adapterPosition; 

    //context of app 
    private Context mContext; 

    //default constructor 
    public ClientesListAdapter(Context context, List<Cliente> clientes) { 

     //context pointer 
     this.mContext = context; 

     //alloc 
     this.clientes = new ArrayList<Cliente>(clientes.size()); 
     this.clientes.addAll(clients); 
    } 

    //Holder for events and dates (memory management) 
    public static class ViewHolder{ 
     TextView myTextView;//this is actually findViewById(R.id.name) @see getView() method 
    } 

    //generated method 
    @Override 
    public int getCount() { 
     // TODO Auto-generated method stub 
     return this.clientes != null ? clientes.size() : 0; 
    } 

    //generated method 
    @Override 
    public Cliente getItem(int position) { 
     return this.clientes.get(position); 
    } 

    //generated method 
    @Override 
    public long getItemId(int position) { 
     // TODO Auto-generated method stub 
     return position; 
    } 

    //get client's id 
    public int getClienteId(int position){ 
     return this.clientes.get(position).getClienteId(); 
    } 

    //get client's id without passing the position 
    public int getClienteId(){ 
     return this.clientes.get(adapterPosition).getClienteId(); 
    } 

    @Override 
    public View getView(int position, View convertView, ViewGroup parent) { 

     //row is actually convertView (the current view) 
     View row = convertView; 
     //holds our view elements 
     ViewHolder holder; 

     //if row is null 
     if(row == null){ 
      //inflate layout to get our view elements 
      LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
      row = inflater.inflate(com.yourapp.R.layout.my_layout, parent, false);//your layout here, modify code 
      //set up the holder 
      holder = new ViewHolder(); 
      holder.myTextView = (TextView) row.findViewById(com.yourapp.R.id.name); 

      //give the row a tag (holder) 
      row.setTag(holder); 

     }else{ 
      //row is not null we can see it (no need to allocate memory) 
      holder = (ViewHolder) row.getTag(); 
     } 

     //get your cliente object 
     Cliente cliente = this.clientes.get(position); 
     if (cliente != null) { 
      holder.myTextView.setText(cliente.getFirstname()); 
     } 

     //copy position 
     adapterPostion = position; 

     return convertView; 
    } 

} 

你看,我們使用的ViewHolder類的內存管理。這是在列表適配器中保存視圖元素的好習慣。你可以找到更多關於列表視圖的信息,由Romain Guy - The World of ListViews解釋。

從您的MainActivity分配適配器並單擊獲取您的項目:

//---- code --- // 
ListView myListView = (ListView)findViewById(R.id.mylistview);//or you may use ListActivity 
ClientesListAdapter adapter = new ClientesListAdapter(this, clientes);//"this" or "getApplicationContext()" 
myListView.setAdapter(adapter); 
adapter.notifyDataSetChanged();//notify 
// ---- code --- // 
@Override 
protected void onListItemClick(ListView l, View v, int position, long id) { 
    Toast.makeText(this, "You have selected" + position + id , 
      Toast.LENGTH_SHORT).show(); 

    Intent intent = new Intent(MyActivity.this, ActivityB.class); 
    intent.putInt("cliente_id",adapter.getClienteId()); 
    startActivity(intent); 
} 

另一個例子是與適配器這樣實現的接口:

//--code// 
//Interface method 
private OnSaveEditsListener saveEditsListener = null; 
public void setOnSaveEditsListener(OnSaveEditsListener l) { 
    saveEditsListener = l; 
} 
//--code// 

    @Override 
    public View getView(final int position, View convertView, ViewGroup parent) { 

     //--code--// 

     //get clicked position of calendar (get clicked day) 
     convertView.setOnClickListener(new OnClickListener() { 

      @Override 
      public void onClick(View v) { 
       v.requestFocusFromTouch(); 
       currentAgendaPosition = position; 
       try{ 
        saveEditsListener.onSaveEdits(); 
       }catch(Exception ex){ 
        ex.printStackTrace(); 
       } 
      } 
     }); 

     //returns current row 
     return row; 
    } 
    //--code--// 

從你MainActivity啓動第二個活動是這樣的:

adapter.setOnSaveEditsListener(new OnSaveEditsListener() { 

    @Override 
    public void onSaveEdits() { 
     //Start activity from here 
     //--code--// 
     startActivity(intent); 
    } 
}); 
+0

感謝您的回答非常有用,我可以更清楚地看到我必須做的事情。再次感謝 – Henry1988

0

獲取被點擊項目的位置,並從陣列列表中獲取該位置的對象,並使用它獲取所需的詳細信息。

使用

@Override 
    protected void onListItemClick(ListView l, View v, int position, long id) { 
     Toast.makeText(this, "You have selected" + position + id , 
       Toast.LENGTH_SHORT).show(); 
     // use this.clientes.get(position) and pass it to the next activity or fragment using putextras to where you need to pass and display this in the destination end using the same object by getting it using getExtra() 

    } 
0

您的列表是在適配器:

private List<Cliente> clientes; 

在onListItemClick,您可以使用位置參數,這個名單得到Cliente。

當您調用startActivity並將其傳遞給一個Intent時,將信息傳遞給另一個活動。這樣做的目的可能有額外的信息,你的情況,你可以設置CUSTOMER_ID爲int額外的,是這樣的:

intent.putExtra(EXTRA_CUSTOMER_ID, customer_id); 
+0

嘿謝謝你的回答,我會盡力的。 – Henry1988