2013-07-28 10 views
7

Chcę mieć AbstractMainActivity, który tworzy szufladę nawigacji. Tam też powinienem obsługiwać kliknięcia pozycji menu, a następnie wywoływać nowe czynności. W tych działaniach chcę ponownie użyć tej samej szuflady nawigacji.Szuflada nawigacji na Androida (działania wywołujące) z AbstractMainActivity

Chciałbym rozszerzyć w Subclasses o AbstractMainActivity i wywołać getLayoutResourceID inaczej z każdej podklasy (zgodnie z sugestią tutaj: android how to create my own Activity and extend it?).

Problem polega na tym, że teraz w AbstractMainActivity, gdzie chcę zbudować szufladę nawigacji, nie mam żadnego dostępu do elementu szuflady nawigacji (xml), ponieważ chcę oczywiście mieć inny układ podstawowy dla podklasy.

Czy muszę "uwzględnić układ" we wszystkich plikach układu podklas? Ale to nie działa, co zrobić źle, jeśli chcę korzystać z działań zamiast fragmentów za pomocą szuflady nawigacji?

public abstract class MainActivity extends Activity { 

private String[] menuItems; 
private DrawerLayout mDrawerLayout; 
private ListView mDrawerList; 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    //setContentView(R.layout.activity_main); 

    setContentView(getLayoutResourceId()); 

    menuItems = getResources().getStringArray(R.array.menu_items); 
    mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout); 
    mDrawerList = (ListView) findViewById(R.id.left_drawer); 

    // Set the adapter for the list view 
    mDrawerList.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, menuItems)); 
    // Set the list's click listener 
    mDrawerList.setOnItemClickListener(new DrawerItemClickListener()); 

} 


protected abstract int getLayoutResourceId(); 

@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; 
} 


private class DrawerItemClickListener implements ListView.OnItemClickListener { 
    @Override 
    public void onItemClick(AdapterView parent, View view, int position, long id) { 
     selectItem(position); 
    } 

    /** Swaps fragments in the main content view */ 
    private void selectItem(int position) { 
     //Fragment fragment = new PlanetFragment(); 
     Bundle args = new Bundle(); 
     // args.putInt(PlanetFragment.ARG_PLANET_NUMBER, position); 

     Intent intent = new Intent(MainActivity.this, ProductListActivity.class); 
     startActivity(intent); 

    } 
} 




public class ProductListActivity extends MainActivity { 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

} 

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

@Override 
protected int getLayoutResourceId() { 
    // TODO Auto-generated method stub 
    return R.layout.activity_product_list; 
} 

to układ listy produktów podklasy (activity_product_list.xml)

<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=".ProductList" > 

<include layout="@layout/activity_main"/> 

<ListView 
    android:id="@+id/listView1" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:layout_centerHorizontal="true" 
    android:layout_centerVertical="true" > 
</ListView> 

to układ szuflady nawigacyjnym (activity_main.xml)

<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android" 
xmlns:android1="http://schemas.android.com/apk/res/android" 
android:id="@+id/drawer_layout" 
android:layout_width="300dp" 
android:layout_height="500dp" > 

<!-- The main content view --> 
<FrameLayout 
    android:id="@+id/content_frame" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" /> 
<!-- The navigation drawer --> 
<ListView android:id="@+id/left_drawer" 
    android:layout_width="240dp" 
    android:layout_height="match_parent" 
    android:layout_gravity="start" 
    android:choiceMode="singleChoice" 
    android:divider="@android:color/transparent" 
    android:dividerHeight="0dp" 
    android:background="#c3c3c3"/> 

Ale to nie działa, ale jeśli go nie mam, otrzymuję wyjątki null-pointera, gdy moja podklasa wywołuje metodę onCreate klasy abstrakcyjnej, w której chcę zbudować szufladę nawigacji, nie znajduje elementów układu do ustaw listy i układ (R.id.left_drawer lub R.id.drawer_layout)!

+0

Co w końcu zrobiłeś? Mam to samo pytanie. – theblang

+0

@mattblang Śledź link [this] (http://naddydroid.blogspot.in/). – Naddy

Odpowiedz

1

To, co zrobiłem w poprzednich aplikacjach, ma menu przesuwne, utworzone jako wywołanie funkcji w abstrakcyjnej aktywności. Po skonfigurowaniu nowego działania rozszerzającego działanie abstrakcyjne wykonywane jest wywołanie funkcji onCreate(). Obecnie pracuję nad podobną implementacją za pomocą szuflady nawigacji, więc nie jestem do końca pewien, czy to działa, ale może być dobrym miejscem do rozpoczęcia pracy. Wszystkie czynności, które będą wywoływać szufladę nawigacji, będą musiały mieć element DrawerLayout jako element najwyższego poziomu układu.

+0

Dzięki, więc moje podejście idzie w dobrym kierunku, włączając w to układ szuflad w układach poddziałań? Wtedy byłbym w stanie ustawić menu szuflady nawigacyjnej w klasie abstrakcyjnej, ale jakoś "nie uwzględnia" jeszcze nie działa. Najgorszy przypadek mam duplikację kodu w układach, ale przynajmniej nie w kodzie działania. –

+0

W prawo. Właśnie to zaimplementowałem i działa. Każdy nowy schemat działań będzie musiał mieć najwyższy poziom DrawerLayout i zawarte w nim elementy szuflady. Powinieneś nadać elementom szuflady taki sam identyfikator, jaki mają w układzie abstrakcyjnym, aby można było ponownie użyć wywołania funkcji odziedziczonego po abstrakcyjnej aktywności dla szuflady. Niestety, ponieważ schemat projektowania systemu Android wydaje się oddalać od wielu działań do jednej aktywności z wieloma fragmentami, nie widzę w najbliższym czasie możliwości dodania funkcji "dołącz". – supern00b

12

Próbuję również dowiedzieć się, jak to zrobić.

Widziałem bardzo dobry samouczek, który robi dokładnie to, co chcesz here. Chodzi o stworzenie abstrakcyjnej klasy aktywności AbstractNavDrawerActivity, z której wszystkie działania z szufladami będą dziedziczyć. Klasa ta wykorzystuje klasę NavDrawerActivityConfiguration fasoli, która przechowuje wszystkie informacje na temat szuflady nav tym układzie, który musi być napompowane

Innym rozwiązaniem byłoby utworzenie klasy NavDrawerUtil gdzie można umieścić metody statyczne, które współdziałają z szufladą nav. Następnie możesz wywoływać te metody z każdego działania, jak potrzebujesz.

Drugie podejście daje większą elastyczność i nie musisz martwić się o kolejność nadpisywania layoutu i takie, ale myślę, że jest to mniej czyste rozwiązanie niż pierwsze z AbstractNavDrawerActivity, że wszystkie działania z szufladą nav dziedziczą od zasugerowałeś.

+0

http://stackoverflow.com/a/4922740/3060087 to prostsze rozwiązanie wykorzystujące to samo podejście. Ten przykład dotyczy implementacji tej samej przesuwnej szuflady w każdym działaniu, ale można go dostosować do szuflady nawigacji, po prostu zastępując LinearLayout w DrawerActivity przez DrawerLayout. – Price

Powiązane problemy