Naviagtion Drawer wie zwischen layouts wechseln?

  • Antworten:36
  • OffenNicht stickyBentwortet
  • Forum-Beiträge: 180

25.06.2014, 19:25:57 via Website

Hallo
Folgendes Zenario :
Ich habe eine app mit einem navigation drawer .... in diesem drawer sind die verschiedenen titel mit einer array dargestellt
nun möchte ich dass wenn man zb auf den 2. titel die dazugehörige xml datei angezeicht wird, widerum bei dem 3. titel die dazugehörtige.....

mein problem ist dass ich den code für den navigation drawer habe und die xml dateien fertig habe, nur nicht weis wie man den code bei "onItemClick" umändern muss dass man zu jedem titel die xml datei angezeigt wird...

Könnt ihr mir helfen ich suche und suche habe aber im internet für meinen code nichts gefunden für onItemClick:

Hier der code "Main Activity"

import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.ActionBarDrawerToggle;
import android.support.v4.widget.DrawerLayout;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.ListView;

import com.hacking.hackstore.R;

public class MainActivity extends Activity {


    // Within which the entire activity is enclosed
    DrawerLayout mDrawerLayout;

    // ListView represents Navigation Drawer
    ListView mDrawerList;

    // ActionBarDrawerToggle indicates the presence of Navigation Drawer in the action bar
    ActionBarDrawerToggle mDrawerToggle;    

    // Title of the action bar
    String mTitle="";

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);


        mTitle = (String) getTitle();       


        // Getting reference to the DrawerLayout
        mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);


        mDrawerList = (ListView) findViewById(R.id.drawer_list);

        // Getting reference to the ActionBarDrawerToggle
        mDrawerToggle = new ActionBarDrawerToggle(  this, 
                                                    mDrawerLayout, 
                                                    R.drawable.ic_drawer, 
                                                    R.string.drawer_open,
                                                    R.string.drawer_close){

            /** Called when drawer is closed */
            public void onDrawerClosed(View view) {
                getActionBar().setTitle(mTitle);
                invalidateOptionsMenu();

            }

            /** Called when a drawer is opened */
            public void onDrawerOpened(View drawerView) {
                getActionBar().setTitle("Menü");
                invalidateOptionsMenu();
            }

        };

        // Setting DrawerToggle on DrawerLayout
        mDrawerLayout.setDrawerListener(mDrawerToggle);

        // Creating an ArrayAdapter to add items to the listview mDrawerList
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(
                    getBaseContext(), 
                    R.layout.drawer_list_item  , 
                    getResources().getStringArray(R.array.rivers) 
                );

        // Setting the adapter on mDrawerList
        mDrawerList.setAdapter(adapter);

        // Enabling Home button
        getActionBar().setHomeButtonEnabled(true);

        // Enabling Up navigation
        getActionBar().setDisplayHomeAsUpEnabled(true);

        // Setting item click listener for the listview mDrawerList
        mDrawerList.setOnItemClickListener(new OnItemClickListener() {


            @Override
            public void onItemClick(AdapterView<?> parent,
                            View view,
                            int position,
                            long id) {          

                // Getting an array of rivers
                String[] rivers = getResources().getStringArray(R.array.rivers);

                //Currently selected river
                mTitle = rivers[position];              


                // Creating a fragment object

                RiverFragment rFragment = new RiverFragment();

                // Creating a Bundle object
                Bundle data = new Bundle();

                // Setting the index of the currently selected item of mDrawerList
                data.putInt("position", position);

                // Setting the position to the fragment
                rFragment.setArguments(data);

                // Getting reference to the FragmentManager
                FragmentManager fragmentManager  = getFragmentManager();

                // Creating a fragment transaction
                FragmentTransaction ft = fragmentManager.beginTransaction();

                // Adding a fragment to the fragment transaction
                ft.replace(R.id.content_frame, rFragment);

                // Committing the transaction
                ft.commit();



                mDrawerList.setItemChecked(position, true);



                // Closing the drawer
                mDrawerLayout.closeDrawer(mDrawerList);             

            }
        }); 
    }



     @Override
     protected void onPostCreate(Bundle savedInstanceState) {
         super.onPostCreate(savedInstanceState);         
         mDrawerToggle.syncState(); 
     }

    /** Handling the touch event of app icon */
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {     
        if (mDrawerToggle.onOptionsItemSelected(item)) {
          return true;
        }
        return super.onOptionsItemSelected(item);
    }


    /** Called whenever we call invalidateOptionsMenu() */
    @Override
    public boolean onPrepareOptionsMenu(Menu menu) {
        // If the drawer is open, hide action items related to the content view
        boolean drawerOpen = mDrawerLayout.isDrawerOpen(mDrawerList);

        menu.findItem(R.id.action_settings).setVisible(!drawerOpen);
        return super.onPrepareOptionsMenu(menu);
    }


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

Falls ihr noch irgend einen code braucht nur sagen!

MFG Lukas R.
Programmieren ist nicht nur eine Wissenschaft, sondern auch ein Lifestyle!

Antworten
  • Forum-Beiträge: 180

26.06.2014, 11:37:09 via App

keiner eine Idee?

MFG Lukas R.
Programmieren ist nicht nur eine Wissenschaft, sondern auch ein Lifestyle!

Antworten
Pascal P.
  • Mod
  • Blogger
  • Forum-Beiträge: 10.182

26.06.2014, 13:50:16 via Website

Wie meinst du das mit "XML anzeigen"
Was soll bei ItemClick konkret Passieren bzw. was soll angezeigt werden.

LG Pascal //It's not a bug, it's a feature. :) ;)

Antworten
  • Forum-Beiträge: 180

26.06.2014, 16:37:57 via App

ja zB wenn man im Menü dann auf den Titel "home" klickt dass dann die "home.XML" angezeigt wird

und was passiert wenn man im Menü auf etwas klickt muss man es ja in "onitemclick" mit einem code definieren

MFG Lukas R.
Programmieren ist nicht nur eine Wissenschaft, sondern auch ein Lifestyle!

Antworten
Pascal P.
  • Mod
  • Blogger
  • Forum-Beiträge: 10.182

26.06.2014, 16:43:38 via Website

Du meinst das Layout soll gewechselt werden, Oser?
Dann würde setContentView passen.
Wenn du aber Fragments benutzt ist es übersichtlicher für jedes XML Laout eie Fragment Klasse zu eröffnen.

LG Pascal //It's not a bug, it's a feature. :) ;)

Antworten
  • Forum-Beiträge: 180

26.06.2014, 18:23:37 via App

ja und wie würde ich den code dann aussehen lassen denn ich möchte es zuerst mal ohne fragments machen da sie bei dieser APP nicht unbedingt notwendig sind?

mit switch und case oder?

MFG Lukas R.
Programmieren ist nicht nur eine Wissenschaft, sondern auch ein Lifestyle!

Antworten
Pascal P.
  • Mod
  • Blogger
  • Forum-Beiträge: 10.182

26.06.2014, 18:26:18 via Website

Ja aber wenn du etwas auf der UI machen willst, zb auf einen Button Reagieren oder Text auswerten, dann wird das alles ein wenig unübersichtlich.
Aber zum Testen reich das, du kannst das Switch/case über die IDs laufen lassen und dann in der Case dein SetCotentView oder wie auch immer machen.

LG Pascal //It's not a bug, it's a feature. :) ;)

Antworten
  • Forum-Beiträge: 180

26.06.2014, 20:02:19 via App

so unübersichtlich finde ich dass nicht?
wird ja alles schön in der swichcase definiert

dass Konzept ist simple dass zB bei case 0 (dem ersten Titel im Menü;) das layout 0 angezeicht wird , bei case 1 dann das layout 1 usw

mein Problem ist aber dass ich nicht weis wie man den code bei onitemclick schreibt

ein bsp wäre hilfreich denn im Internet habe ich für meinen code keinen passenden onitemclick code gefunden der für Layouts mit setcontentview funktioniert

MFG Lukas R.
Programmieren ist nicht nur eine Wissenschaft, sondern auch ein Lifestyle!

Antworten
Pascal P.
  • Mod
  • Blogger
  • Forum-Beiträge: 10.182

26.06.2014, 20:31:42 via Website

In eine Andere Funktion auslagern hilft.
Dann musst du nicht aus der anonymen listener Klasse auf die Activity zugreifen.

LG Pascal //It's not a bug, it's a feature. :) ;)

Flo R.

Antworten
  • Forum-Beiträge: 180

26.06.2014, 21:36:22 via App

OK dass hab ich nicht verstanden?
Wenn du mir ein Beispiel geben könntest wäre ich dir sehr hilfreich

denn in meinem geposteten code ist bei in item click schon ein Fragment drinen und es funktioniert aber wie ich den code für mehrere schreibe weis ich nich

MFG Lukas R.
Programmieren ist nicht nur eine Wissenschaft, sondern auch ein Lifestyle!

Antworten
Pascal P.
  • Mod
  • Blogger
  • Forum-Beiträge: 10.182

27.06.2014, 05:57:36 via App

Also willst du es doch für Fragments machen und nicht anders.
Das ist ok.
Du musst halt entsprechend zur gecklickten id in deiner swich reagieren und ein neues Fragment zurückgeben, welches das alte ersetzt.
Was ist daran nicht verständlich?

LG Pascal //It's not a bug, it's a feature. :) ;)

Antworten
  • Forum-Beiträge: 76

27.06.2014, 15:35:30 via Website

Mit dem was Pascal geschrieben hat und der Doku solltest du das eigentlich hinbekommen

Antworten
  • Forum-Beiträge: 180

27.06.2014, 16:03:23 via App

ja dass Prinzip verstehe ich schon wie Pascal beschrieben hat nur fehlt mir dass wissen den code an sich in der switch und case Option bei onitemclick zu schreiben

MFG Lukas R.
Programmieren ist nicht nur eine Wissenschaft, sondern auch ein Lifestyle!

Antworten
Pascal P.
  • Mod
  • Blogger
  • Forum-Beiträge: 10.182

27.06.2014, 16:31:17 via Website

Also ich würde das so machen:

public void selectFrag(int itemPosition) { 



  FragmentManager fm = getFragmentManager(); 
  FragmentTransaction fragmentTransaction = fm.beginTransaction(); 
  fragmentTransaction.replace(R.id.fragment_place, getFragmentById(itemPosition)); 
  fragmentTransaction.commit(); 





} 


public Fragment getFragmentById(int position)
{
switch(position)
{
 case 0: return new Fragment1();
 case 1: retrun new Fragment2();
 //Und so weiter
}
return new Fragment1();

}

Jetzt muss die SelectFrag Methode nurnoch im Listener des items aufgerufen werden.

LG Pascal //It's not a bug, it's a feature. :) ;)

Antworten
  • Forum-Beiträge: 180

27.06.2014, 17:49:24 via App

nach sowas hab ich gesucht danke werde sie sobalt möglich aus probieren und das Ergebnis hier hineinschreiben

MFG Lukas R.
Programmieren ist nicht nur eine Wissenschaft, sondern auch ein Lifestyle!

Antworten
Pascal P.
  • Mod
  • Blogger
  • Forum-Beiträge: 10.182

27.06.2014, 20:00:34 via Website

Das findet man aber in jedem guten Tut über Fragments.
Eigentlich hätte dir das auch selber einfallen können

LG Pascal //It's not a bug, it's a feature. :) ;)

Antworten
  • Forum-Beiträge: 180

27.06.2014, 20:06:36 via Website

public void selectItem(int position)
    {
         switch(position)
         {
              case 0:

                         FragmentManager fragmentManager = getFragmentManager();
                         FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();   
                         Fragment fragment = new Home();
                         fragmentTransaction.add(R.id.content_frame, fragment);
                         fragmentTransaction.commit();

              break;
              case 1:

              break; 
              case 2:

              break;
         } 
    }

ich habs jetzt mal so gemacht und es zeigt mir momentan nur einen Fehler bei

  Fragment fragment = new Home();

an: "Type mismatch: cannot convert from Home to Fragment"

Also die MainActivity wo dieser code drinnen ist importet: " import android.app.Fragment; "
Und die Home.class importet: "import android.support.v4.app.Fragment;"

MFG Lukas R.
Programmieren ist nicht nur eine Wissenschaft, sondern auch ein Lifestyle!

Antworten
Pascal P.
  • Mod
  • Blogger
  • Forum-Beiträge: 10.182

27.06.2014, 20:43:56 via Website

Wie sieht denn dein HomeFragment Klasse aus?

LG Pascal //It's not a bug, it's a feature. :) ;)

Antworten
  • Forum-Beiträge: 180

27.06.2014, 21:11:58 via Website

Okey den oben beschriebenen Fehler habe ich schon selber beheben können
Jetzt sieht der Code so aus ohne Fehler:

mDrawerList.setOnItemClickListener(new OnItemClickListener() {

            public void onItemClick(AdapterView<?> parent,
            View view,
            int position,
            long id){

        String[] rivers = getResources().getStringArray(R.array.rivers);
        mTitle = rivers[position];              

         switch(position)
         {
              case 0:
                         // fragment1
                         // use fragment transaction and add the fragment to the container
                         android.app.FragmentManager fragmentManager = getFragmentManager();
                         android.app.FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();   
                         android.app.Fragment fragment = new Home();
                         fragmentTransaction.add(R.id.content_frame, fragment);
                         fragmentTransaction.commit();

              break;
              case 1:
                         android.app.FragmentManager fragmentManagera = getFragmentManager();
                         android.app.FragmentTransaction fragmentTransactiona = fragmentManagera.beginTransaction();   
                         android.app.Fragment afragment = new Home();
                         fragmentTransactiona.add(R.id.content_frame, afragment);
                         fragmentTransactiona.commit();
              break; 
              case 2:
                         android.app.FragmentManager fragmentManagerb = getFragmentManager();
                         android.app.FragmentTransaction fragmentTransactionb = fragmentManagerb.beginTransaction();   
                         android.app.Fragment fragmentb = new Simpsons();
                         fragmentTransactionb.add(R.id.content_frame, fragmentb);
                         fragmentTransactionb.commit();
              break;
         } 

         mDrawerList.setItemChecked(position, true);
         mDrawerLayout.closeDrawer(mDrawerList);            
    }




        });
    }

Doch 1nen Fehler habe ich jetzt noch:
Wenn ich die App jetzt ausführe startet sie normal doch wenn ich im Menü jetzt zb auf Home klicke kommt der Fehler:
java.lang.NullPointerExpection
at in.wptrafficanalyzer.navigationdrawerdemo.Home.<init>(Home.java:17)

dass ist der Home Code:

import android.content.Context;
import android.os.Bundle;
import android.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListView;


public  class Home extends Fragment {

    int position = getArguments().getInt(&quot;position&quot;);
    String[] rivers = getResources().getStringArray(R.array.rivers);





    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        View root = inflater.inflate(R.layout.home, container, false);
        getActivity().getActionBar().setTitle(rivers[position]);


        return root;

    }
}

MFG Lukas R.
Programmieren ist nicht nur eine Wissenschaft, sondern auch ein Lifestyle!

Antworten
Pascal P.
  • Mod
  • Blogger
  • Forum-Beiträge: 10.182

27.06.2014, 23:07:50 via Website

Ist klar:

 int position = getArguments().getInt(&amp;quot;position&amp;quot;);
String[] rivers = getResources().getStringArray(R.array.rivers);

Diese beiden Zeilen müssen in einer Methode stehen.
Hier bietet sich der Konstruktor an, da brauchst du ach keine get Arguments oder so, sondern du übergibst dem Fragment einfach deine Parameter beim Aufrufen.

Beispiel:

public Home(int Position)
{
this.position =Position;
}

`case 0:
// fragment1
// use fragment transaction and add the fragment to the container
android.app.FragmentManager fragmentManager = getFragmentManager();
android.app.FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
android.app.Fragment fragment = new Home();
fragmentTransaction.add(R.id.content_frame, fragment);
fragmentTransaction.commit();

          break;
          case 1:
                     android.app.FragmentManager fragmentManagera = getFragmentManager();
                     android.app.FragmentTransaction fragmentTransactiona = fragmentManagera.beginTransaction();   
                     android.app.Fragment afragment = new Home();
                     fragmentTransactiona.add(R.id.content_frame, afragment);
                     fragmentTransactiona.commit();
          break; 

`

Jetzt mal ganz ehrlich, dieser Code ist so ineffizient!!!!
ist dir nicht aufgefallen, dass in jeder Case das gleiche steht bis auf das das Fragment ein anderes ist.
Mache dies Effizienter durch den Weg den ich dir gezeigt habe.

  public void onItemClick(AdapterView&amp;lt;?&amp;gt; parent,
        View view,
        int position,
        long id){

    String[] rivers = getResources().getStringArray(R.array.rivers);
    mTitle = rivers[position];              


                     android.app.FragmentManager fragmentManager = getFragmentManager();
                     android.app.FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();   

                     fragmentTransaction.add(R.id.content_frame, getFragment());
                     fragmentTransaction.commit();
                     }

                     publlic Fragment getFragment(int pos)
                     {
                     switch(pos)
                     {
                     case 0: return new Home(pos);
                     }
                     }

Edit: Du musst aufpassen, aus einem Fragment kannst du keine ActionBar Änderungen Machen (Titel) da musst du die Activity für benutzen.

— geändert am 27.06.2014, 23:10:51

LG Pascal //It's not a bug, it's a feature. :) ;)

Antworten

Empfohlene Artikel