2013-08-23 1 views
16

Come utilizzare ActionBarActivity di "android-support-v7-appcompat" nell'attività che estende ListActivity.ActionBarActivity di "android-support-v7-appcompat" e ListActivity nella stessa attività

Per esempio io ho un'attività

public class xxxxxListActivity 
    extends ListActivity implements OnItemSelectedListener { 
    // ................... 
} 

Nell'attività sopra voglio usare "ActionBarActivity", ma come java dosent supporta l'ereditarietà multipla non sono in grado di farlo funzionare.

+3

usare 'ActionBarActivity' e attuare il' ListView' da soli. – Luksprog

risposta

41

Ecco un'implementazione di ActionBarListActivity:

public abstract class ActionBarListActivity extends ActionBarActivity { 

private ListView mListView; 

protected ListView getListView() { 
    if (mListView == null) { 
     mListView = (ListView) findViewById(android.R.id.list); 
    } 
    return mListView; 
} 

protected void setListAdapter(ListAdapter adapter) { 
    getListView().setAdapter(adapter); 
} 

protected ListAdapter getListAdapter() { 
    ListAdapter adapter = getListView().getAdapter(); 
    if (adapter instanceof HeaderViewListAdapter) { 
     return ((HeaderViewListAdapter)adapter).getWrappedAdapter(); 
    } else { 
     return adapter; 
    } 
} 
} 

Proprio come ListActivity regolare, avrete bisogno di un layout che contiene un ListView con l'ID android.R.id.list ("@android: id/list "in XML).

Lo spiel in getListAdapter() è per gestire i casi in cui le visualizzazioni di intestazione sono state aggiunte a ListView. Sembra che ListView abbia impostato il proprio adattatore su un HeaderViewListAdapter, quindi dobbiamo provare e ottenere l'adattatore avvolto per evitare errori di trasmissione.

Edit: prova ad aggiungere questa funzione per soddisfare il bisogno di onListItemClick:

protected void onListItemClick(ListView lv, View v, int position, long id) { 
    getListView().getOnItemClickListener().onItemClick(lv, v, position, id); 
} 
+0

Ciao .. Ho provato a implementare questa soluzione. Ma ottengo il metodo Can not Resolve findViewById. Qualche idea del perché la mia applicazione fallisce su questa linea ?? –

+0

ottimo. Ma, sembra, per completare _ActionBarListActivity_ deve contenere l'implementazione _onListItemClick_. Puoi aggiungerlo? – Sash0k

+0

@ this-Me Sono presenti tutte le importazioni necessarie? findViewById è ereditato da ActionBarActivity, quindi se ci sono problemi con quella linea assicurati che la classe corretta sia estesa: import android.support.v7.app.ActionBarActivity; –

2

Forse si può provare ad estendere ActionBarActivity e per il layout predefinito per quell'attività impostare un layout con ListView.

Qualcosa di simile a questo:

public class AlarmListActivity extends ActionBarActivity { 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.layout_with_list_view); 

     ListView lv = (ListView) findViewById(R.id.listView1); 
     // populate list view 
    } 
} 

e correcponding file di layout:

<LinearLayout> 
    <ListView 
     android:id="@+id/listView1"> 
    </ListView> 
</LinearLayout> 
0

Invece di creare il layout in XML, ho deciso di farlo in codice. Il file a è una sola goccia in sostituzione nel codice.

package com.stackoverflow.free.examples; 

import android.os.Bundle; 
import android.support.v7.app.ActionBarActivity; 
import android.view.View; 
import android.widget.AdapterView; 
import android.widget.LinearLayout; 
import android.widget.ListAdapter; 
import android.widget.ListView; 
import android.widget.TableRow; 
import android.widget.TextView; 

/** 
* based of https://raw.githubusercontent.com/android/platform_frameworks_base/d6c1919779acb042392615637b9007e0c4b89023/core/java/android/app/ListActivity.java 
* Created by elcuco on 5/27/2014. 
*/ 
@SuppressWarnings("UnusedDeclaration") 
public class SupportListActivity extends ActionBarActivity { 
    protected ListAdapter mAdapter; 
    protected ListView mList; 
    protected TextView mEmptyMessage; 

    @Override 
    protected void onCreate(Bundle savedBundle) 
    { 
     super.onCreate(savedBundle); 
     mEmptyMessage = new TextView(this); 
     mEmptyMessage.setText("No results"); 
     mList = new ListView(this); 
     mList.setEmptyView(mEmptyMessage); 
     LinearLayout ll = new LinearLayout(this); 
     ll.addView(mEmptyMessage, TableRow.LayoutParams.MATCH_PARENT, TableRow.LayoutParams.MATCH_PARENT); 
     ll.addView(mList, TableRow.LayoutParams.MATCH_PARENT, TableRow.LayoutParams.MATCH_PARENT); 
     setContentView(ll); 
    } 

    public void setListAdapter(ListAdapter adapter) { 
     synchronized (this) { 
      mAdapter = adapter; 
      mList.setAdapter(adapter); 
     } 
    } 

    /** 
    * Get the activity's list view widget. 
    */ 
    public ListView getListView() { 
     return mList; 
    } 

    /** 
    * Set the currently selected list item to the specified 
    * position with the adapter's data 
    * 
    * @param position the position on list to select 
    */ 
    public void setSelection(int position) { 
     mList.setSelection(position); 
    } 

    /** 
    * Get the position of the currently selected list item. 
    */ 
    public int getSelectedItemPosition() { 
     return mList.getSelectedItemPosition(); 
    } 

    /** 
    * Get the cursor row ID of the currently selected list item. 
    */ 
    public long getSelectedItemId() { 
     return mList.getSelectedItemId(); 
    } 

    private AdapterView.OnItemClickListener mOnClickListener = new AdapterView.OnItemClickListener() { 
     public void onItemClick(AdapterView<?> parent, View v, int position, long id) 
     { 
      onListItemClick((ListView)parent, v, position, id); 
     } 
    }; 

    /** 
    * This method will be called when an item in the list is selected. 
    * Subclasses should override. Subclasses can call 
    * getListView().getItemAtPosition(position) if they need to access the 
    * data associated with the selected item. 
    * 
    * @param l The ListView where the click happened 
    * @param v The view that was clicked within the ListView 
    * @param position The position of the view in the list 
    * @param id The row id of the item that was clicked 
    */ 
    protected void onListItemClick(ListView l, View v, int position, long id) { 
    } 
} 
0

mia risposta basata su accepted one, e contiene anche onListItemClick attuazione. Ma ha un problema con la vista vuota.

public abstract class ActionBarListActivity extends ActionBarActivity { 

private ListView mListView; 

protected ListView getListView() { 
    if (mListView == null) { 
     mListView = (ListView) findViewById(android.R.id.list); 
     mListView.setOnItemClickListener(mOnClickListener); 
    } 
    return mListView; 
} 

protected void setListAdapter(ListAdapter adapter) { 
    getListView().setAdapter(adapter); 
} 

protected ListAdapter getListAdapter() { 
    ListAdapter adapter = getListView().getAdapter(); 
    if (adapter instanceof HeaderViewListAdapter) { 
     return ((HeaderViewListAdapter) adapter).getWrappedAdapter(); 
    } else { 
     return adapter; 
    } 
} 

protected void onListItemClick(ListView l, View v, int position, long id) { } 

private AdapterView.OnItemClickListener mOnClickListener = new AdapterView.OnItemClickListener() { 
    public void onItemClick(AdapterView<?> parent, View v, int position, long id) { 
     onListItemClick((ListView) parent, v, position, id); 
    } 
}; 
} 
0

Questa soluzione si basa sulla accepted solution da @patrick. Ecco il codice completo:

Prima il file di layout XML activity_main.xml. Si noti che ho un ListView con ID entryList

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:paddingBottom="@dimen/activity_vertical_margin" 
    android:paddingLeft="@dimen/activity_horizontal_margin" 
    android:paddingRight="@dimen/activity_horizontal_margin" 
    android:paddingTop="@dimen/activity_vertical_margin" 
    tools:context="com.example.MainActivity" > 

    <ListView 
     android:id="@+id/entryList" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" > 
    </ListView> 

</RelativeLayout> 

successivo è la mia ActionBarListActivity. Noteresti alcune modifiche. Volevo renderlo generico e riusabile il più possibile.

package com.example.api; 

import android.support.v7.app.ActionBarActivity; 
import android.view.View; 
import android.widget.AdapterView; 
import android.widget.AdapterView.OnItemClickListener; 
import android.widget.HeaderViewListAdapter; 
import android.widget.ListAdapter; 
import android.widget.ListView; 

public abstract class ActionBarListActivity extends ActionBarActivity { 

    private final class ListOnItemClickListener implements OnItemClickListener { 

     public void onItemClick(AdapterView<?> lv, View v, int position, long id) { 
      onListItemClick((ListView) lv, v, position, id); 
      // String str = ((TextView) arg1).getText().toString(); 
      // Toast.makeText(getBaseContext(), str, 
      // Toast.LENGTH_LONG).show(); 
      // Intent intent = new Intent(getBaseContext(), 
      // your_new_Intent.class); 
      // intent.putExtra("list_view_value", str); 
      // startActivity(intent); 
     } 
    } 

    private ListView mListView; 

    protected ListView getListView() { 

     if (mListView == null) { 
      initListView(); 
     } 
     return mListView; 
    } 

    private void initListView() { 
     mListView = (ListView) findViewById(getListViewId()); 
     if (mListView == null) { 
      throw new RuntimeException(
        "ListView cannot be null. Please set a valid ListViewId"); 
     } 

     mListView.setOnItemClickListener(new ListOnItemClickListener()); 
    } 

    protected abstract int getListViewId(); 

    protected void setListAdapter(ListAdapter adapter) { 
     getListView().setAdapter(adapter); 
    } 

    protected void onListItemClick(ListView lv, View v, int position, long id) { 
     // No default functionality. To override 
    } 

    protected ListAdapter getListAdapter() { 
     ListAdapter adapter = getListView().getAdapter(); 
     if (adapter instanceof HeaderViewListAdapter) { 
      return ((HeaderViewListAdapter) adapter).getWrappedAdapter(); 
     } else { 
      return adapter; 
     } 
    } 
} 

Avanti è il mio MainActivity che estende la classe di cui sopra.

package com.example; 

import android.os.Bundle; 
import android.util.Log; 
import android.view.Menu; 
import android.view.MenuItem; 
import android.view.View; 
import android.widget.ArrayAdapter; 
import android.widget.ListView; 
import android.widget.Toast; 

import com.example.api.ActionBarListActivity; 

public class MainActivity extends ActionBarListActivity { 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     String[] values = new String[] { "Android", "iPhone", "WindowsMobile", 
       "Blackberry", "WebOS", "Ubuntu", "Windows7", "Max OS X", 
       "Linux", "OS/2" }; 
     ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, 
       android.R.layout.simple_list_item_1, values); 
     setListAdapter(adapter); 
    } 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     // Inflate the menu; this adds items to the action bar if it is present. 
     getMenuInflater().inflate(R.menu.main, menu); 
     return true; 
    } 

    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
     // Handle action bar item clicks here. The action bar will 
     // automatically handle clicks on the Home/Up button, so long 
     // as you specify a parent activity in AndroidManifest.xml. 
     int id = item.getItemId(); 
     if (id == R.id.action_settings) { 
      return true; 
     } 
     return super.onOptionsItemSelected(item); 
    } 

    @Override 
    protected void onListItemClick(ListView l, View v, int position, long id) { 
     Log.d("click", "Position click " + position); 
     String item = (String) getListAdapter().getItem(position); 
     Toast.makeText(this, item + " selected", Toast.LENGTH_LONG).show(); 
    } 

    @Override 
    protected int getListViewId() { 
     return R.id.entryList; 
    } 
} 

In sostanza, sovrascrivendo onListItemClick() si può dire che cosa fare quando l'utente accetta qualcosa.

Fammi sapere i tuoi pensieri/problemi nei commenti.

Acclamazioni

0

Add seguente riga di codice alla classe e assicurarsi che la classe implementa AdapterView.OnItemClickListener:

getListView().setOnItemClickListener(this);