Autore Topic: BroadcastReciver in NavigationDrawer  (Letto 607 volte)

Offline fabio.dnaweb

  • Nuovo arrivato
  • *
  • Post: 15
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Samsung 19100
  • Sistema operativo:
    Windows 7
BroadcastReciver in NavigationDrawer
« il: 15 Gennaio 2016, 16:41:28 CET »
0
Salve ragazzi ecco il mio scenario:

MainActivity (presente per tutta la vita dell'app)
|_HomeFragment
|_DocumentFragment --> (I fragment sostituiscono la HomePrincipale a seconda delle voci del NavDrawerSelezionato)
|_ContactFragment

A seconda dell'elemento scelto (Home, Document o Contact) il NavDrawer mantiene selezionato l'item scelto.

Poiché dalla Home principale posso scegliere di richiamare i diversi fragment (Document e Contact) ho necessità che nel NavDrawer venga evidenziato l'elemento scelto da una view differente, in questo caso la Home.

Ho pensato di implementare un BroadcastReciver nel DrawerFragment ma il problema è che non posso de-registrare il relativo reciver poiché sia la MainActivity che il DrawerFragment non subiscono mai eventi di "OnPause".
Avete soluzioni alternative per evidenziare l'elemento del menu da una view differente?

Grazie per il vostro contributo.

Offline tonno16

  • Utente storico
  • *****
  • Post: 1169
  • Respect: +56
    • Mostra profilo
  • Dispositivo Android:
    moto g
  • Play Store ID:
    Diego Tonini
  • Sistema operativo:
    OpenSuse
Re:BroadcastReciver in NavigationDrawer
« Risposta #1 il: 15 Gennaio 2016, 22:12:10 CET »
0
Sinceramente non ho capito bene

Offline fabio.dnaweb

  • Nuovo arrivato
  • *
  • Post: 15
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Samsung 19100
  • Sistema operativo:
    Windows 7
Re:BroadcastReciver in NavigationDrawer
« Risposta #2 il: 16 Gennaio 2016, 18:39:43 CET »
0
In effetti hai ragione, mi sono espresso male;
per farla breve ho necessità che la voce di menù all'interno del navigation drawer venga selezionata da una view esterna.

Thx  ;-)

Offline iClaude

  • Utente normale
  • ***
  • Post: 177
  • Respect: +11
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy S5
  • Sistema operativo:
    Windows 10
Re:BroadcastReciver in NavigationDrawer
« Risposta #3 il: 18 Gennaio 2016, 12:14:50 CET »
0
Cosa intendi per view esterna?

Offline fabio.dnaweb

  • Nuovo arrivato
  • *
  • Post: 15
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Samsung 19100
  • Sistema operativo:
    Windows 7
Re:BroadcastReciver in NavigationDrawer
« Risposta #4 il: 18 Gennaio 2016, 12:33:04 CET »
0
Intendo View Button

Offline tonno16

  • Utente storico
  • *****
  • Post: 1169
  • Respect: +56
    • Mostra profilo
  • Dispositivo Android:
    moto g
  • Play Store ID:
    Diego Tonini
  • Sistema operativo:
    OpenSuse
Re:BroadcastReciver in NavigationDrawer
« Risposta #5 il: 18 Gennaio 2016, 13:11:49 CET »
0
Quello che dici non ha senso secondo me :)

Offline fabio.dnaweb

  • Nuovo arrivato
  • *
  • Post: 15
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Samsung 19100
  • Sistema operativo:
    Windows 7
Re:BroadcastReciver in NavigationDrawer
« Risposta #6 il: 18 Gennaio 2016, 14:19:24 CET »
0
Ok non importa.

Grazie ugualmente per il vostro tempo  :-)

Online Ohmnibus

  • Utente senior
  • ****
  • Post: 583
  • Respect: +130
    • Google+
    • @ohmnibus
    • Mostra profilo
    • Lords of Knowledge GdR
  • Dispositivo Android:
    Samsung Galaxy Nexus
  • Play Store ID:
    Ohmnibus
  • Sistema operativo:
    Windows 7 x64
Re:BroadcastReciver in NavigationDrawer
« Risposta #7 il: 18 Gennaio 2016, 14:36:40 CET »
0
In MainActivity metti un metodo pubblico

Codice (Java): [Seleziona]
void selezionaVoce(int voce) {
  //codice per evidenziare la voce scelta
}

Nei vari fragment puoi fare

Codice (Java): [Seleziona]
((MainActivity)getActivity()).selezionaVoce(codiceVoce);
per invocare il metodo di MainActivity
Ohmnibus
Le mie app su Play Store

È stata trovata una soluzione al tuo problema? Evidenzia il post più utile premendo . È un ottimo modo per ringraziare chi ti ha aiutato.

Offline iClaude

  • Utente normale
  • ***
  • Post: 177
  • Respect: +11
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy S5
  • Sistema operativo:
    Windows 10
Re:BroadcastReciver in NavigationDrawer
« Risposta #8 il: 18 Gennaio 2016, 14:54:36 CET »
0
In MainActivity metti un metodo pubblico

Codice (Java): [Seleziona]
void selezionaVoce(int voce) {
  //codice per evidenziare la voce scelta
}

Nei vari fragment puoi fare

Codice (Java): [Seleziona]
((MainActivity)getActivity()).selezionaVoce(codiceVoce);
per invocare il metodo di MainActivity

Ok, se il problema era questo il codice che hai inserito funziona certamente,  ma non è la soluzione migliore.
Il metodo migliore è disaccoppiare (decouple) i componenti e gestire la comunicazione tramite un'interfaccia che l'Activity deve implementare, come spiegato qua:
Communicating with Other Fragments | Android Developers

o anche in questa risposta di StackOverflow (la risposta giusta è la seconda nella lista, n. 65, vedi anche i commenti):
http://stackoverflow.com/questions/12659747/call-an-activity-method-from-a-fragmen

Ciao.

Online Ohmnibus

  • Utente senior
  • ****
  • Post: 583
  • Respect: +130
    • Google+
    • @ohmnibus
    • Mostra profilo
    • Lords of Knowledge GdR
  • Dispositivo Android:
    Samsung Galaxy Nexus
  • Play Store ID:
    Ohmnibus
  • Sistema operativo:
    Windows 7 x64
Re:BroadcastReciver in NavigationDrawer
« Risposta #9 il: 18 Gennaio 2016, 15:17:43 CET »
0

Quella che ho proposto è la versione "quick & dirty" della best practice.

Il succo è quello di invocare un metodo esposto dall'activity che contiene i fragment, la quale eventualmente farà dispatch del messaggio ad altri fragment.

Se poi si usa un'interfaccia esposta dal Fragment che funge da contract ovviamente è meglio, ma visto che FORSE non è quello che fabio.dnaweb sta chiedendo non mi sono perso in dettagli.


P.S.: 65 è il numero degli upvote, non il numero della risposta
Ohmnibus
Le mie app su Play Store

È stata trovata una soluzione al tuo problema? Evidenzia il post più utile premendo . È un ottimo modo per ringraziare chi ti ha aiutato.

Offline iClaude

  • Utente normale
  • ***
  • Post: 177
  • Respect: +11
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy S5
  • Sistema operativo:
    Windows 10
Re:BroadcastReciver in NavigationDrawer
« Risposta #10 il: 18 Gennaio 2016, 15:24:53 CET »
0
Quella che ho proposto è la versione "quick & dirty" della best practice.

Il succo è quello di invocare un metodo esposto dall'activity che contiene i fragment, la quale eventualmente farà dispatch del messaggio ad altri fragment.

Se poi si usa un'interfaccia esposta dal Fragment che funge da contract ovviamente è meglio, ma visto che FORSE non è quello che fabio.dnaweb sta chiedendo non mi sono perso in dettagli.


P.S.: 65 è il numero degli upvote, non il numero della risposta

Ciao, in realtà non si tratta di semplici dettagli, perché il decoupling dei componenti è uno dei concetti fondamentali della programmazione ad oggetti, su cui si basano sostanzialmente tutti i design pattern, a partire da quelli della Gang of Four. Insomma è ciò che distingue un software professionale da uno dilettantistico.
Cmq la mia non era una critica alla tua risposta, che cmq funziona, ma un contributo costruttivo alla discussione.

Offline fabio.dnaweb

  • Nuovo arrivato
  • *
  • Post: 15
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Samsung 19100
  • Sistema operativo:
    Windows 7
Re:BroadcastReciver in NavigationDrawer
« Risposta #11 il: 19 Gennaio 2016, 10:36:18 CET »
0
Grazie ragazzi per il vostro interesse e per le vostre risposte, vi posto il mio attuale codice in modo da poter lavorare direttamente su quello.

Questa è la MainActivity:
Codice (Java): [Seleziona]
public class MainActivity extends BaseActivity
                implements DrawerFragment.OnDrawerItemChangeListener, Toolbar.OnMenuItemClickListener {
        private final static String TAG = "MainActivity";
        @InjectView(R.id.drawer_layout)
        DrawerLayout drawerLayout;

        @Override
        protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.activity_main);
                ButterKnife.inject(this);

                if (savedInstanceState == null)
                        getSupportFragmentManager().beginTransaction()
                                        .replace(R.id.container, new StartFragment(), "fragment_start")
                                        .commit();
        }


        public void toggleDrawer() {
                if (drawerLayout.isDrawerOpen(Gravity.LEFT))
                        drawerLayout.closeDrawer(Gravity.LEFT);
                else
                        drawerLayout.openDrawer(Gravity.LEFT);
        }


        @Override
        public void onDrawerItemChange(EDrawerItem menuItem, boolean toggleMenu) {
                if (toggleMenu)
                        toggleDrawer();

                Fragment f = new StartFragment();
                String tag = "fragment_start";
                switch (menuItem) {
                        case HOME:
                                break;
                        case CALENDAR:
                                f = new CalendarFragment();
                                tag = "fragment_calendar";
                                break;
                        case DOCUMENTS:
                                f = new DocumentsListFragment();
                                tag = "fragment_documents_list";
                                break;
                        case CONTACTS:
                                f = new ContactsListFragment();
                                tag = "fragment_contacts_list";
                                break;
                }
                getSupportFragmentManager().beginTransaction()
                                .replace(R.id.container, f, tag)
                                .commitAllowingStateLoss();
        }
}

Questo è lo StartFragment ovvero la Home principale:
Codice (Java): [Seleziona]
public class StartFragment extends BaseFragment implements View.OnClickListener {

    public StartFragment() {
    }

    @Override
    public void onClick(View v) {
        MainActivity a = (MainActivity) getActivity();
        switch (v.getId()) {
            case R.id.container_calendar:
                a.onDrawerItemChange(EDrawerItem.CALENDAR, false);
                break;
            case R.id.container_documents:
                a.onDrawerItemChange(EDrawerItem.DOCUMENTS, false);
                break;
        }
    }
}

Enum EDrawerItem:
Codice (Java): [Seleziona]
public enum EDrawerItem {
        HOME(0), CALENDAR(1), DOCUMENTS(2), CONTACTS(3);

        private int value;

        EDrawerItem(int value) {
                this.value = value;
        }


        public static EDrawerItem valueFromInt(int v) {
                EDrawerItem item = HOME;
                switch (v) {
                        case 0:
                                item = HOME;
                                break;
                        case 1:
                                item = CALENDAR;
                                break;
                        case 2:
                                item = DOCUMENTS;
                                break;
                        case 3:
                                item = CONTACTS;
                                break;
                }
                return item;
        }
}

Il DrawerFragment:
Codice (Java): [Seleziona]
public class DrawerFragment extends Fragment implements AdapterView.OnItemClickListener {

        @InjectView(android.R.id.list)
        ListView list;

        private DrawerAdapter mAdapter;
        private OnDrawerItemChangeListener mCallback;


        public DrawerFragment() {
        }


        @Override
        public void onAttach(Activity activity) {
                super.onAttach(activity);
                if (activity instanceof OnDrawerItemChangeListener) {
                        this.mCallback = (OnDrawerItemChangeListener) activity;
                }
        }


        @Override
        public void onDetach() {
                super.onDetach();
                mCallback = null;
        }


        @Override
        public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
                return inflater.inflate(R.layout.fragment_drawer, container, false);
        }


        @Override
        public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
                super.onViewCreated(view, savedInstanceState);
                ButterKnife.inject(this, view);


                mAdapter = new DrawerAdapter(getActivity());

                list.setDividerHeight(0);
                list.setAdapter(mAdapter);
                list.setOnItemClickListener(this);
        }


        @Override
        public void onDestroyView() {
                super.onDestroyView();
                ButterKnife.reset(this);
        }


        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                if (mCallback != null)
                        mCallback.onDrawerItemChange(EDrawerItem.valueFromInt(position), true);
                mAdapter.setSelectedIndex(position);
                mAdapter.notifyDataSetChanged();
        }


        public interface OnDrawerItemChangeListener {
                public void onDrawerItemChange(EDrawerItem menuItemId, boolean toggleMenu);
        }

}

E per ultimo l'adapter per il Drawer:
Codice (Java): [Seleziona]
public class DrawerAdapter extends BaseAdapter {

        private Context mContext;
        private List<DrawerItem> mItems;
        private int mSelectedIndex;


        public DrawerAdapter(Context context) {
                this.mContext = context;

                List<DrawerItem> items = new ArrayList<>();
                items.add(new DrawerItem(R.drawable.sidemenu_logo, 0));
                items.add(new DrawerItem(R.drawable.sidemenu_calendar_selector, R.string.label_sidemenu_calendar));
                items.add(new DrawerItem(R.drawable.sidemenu_documents_selector, R.string.label_sidemenu_documents));
                items.add(new DrawerItem(R.drawable.sidemenu_contacts_selector, R.string.label_sidemenu_contacts));
                this.mItems = items;
        }


        @Override
        public int getCount() {
                return mItems.size();
        }


        @Override
        public DrawerItem getItem(int position) {
                return mItems.get(position);
        }


        @Override
        public long getItemId(int position) {
                return position;
        }


        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
                View v = convertView;
                if (v == null) {
                        v = LayoutInflater.from(mContext).inflate(R.layout.item_drawer, parent, false);
                        v.setTag(new ViewHolder(v));
                }

                DrawerItem item = getItem(position);

                ViewHolder vh = (ViewHolder) v.getTag();
                vh.content.setBackgroundResource(item.icon);
                vh.content.setSelected(position == mSelectedIndex);

                boolean hasName = item.name != 0;
                if (hasName)
                        vh.text1.setText(item.name);
                vh.text1.setVisibility(hasName ? View.VISIBLE : View.GONE);

                return v;
        }


        public static class DrawerItem {

                public DrawerItem(int icon, int name) {
                        this.icon = icon;
                        this.name = name;
                }


                int icon;
                int name;
        }

        static class ViewHolder {
                @InjectView(android.R.id.text1)
                TextView text1;
                @InjectView(android.R.id.content)
                FrameLayout content;


                ViewHolder(View view) {
                        ButterKnife.inject(this, view);
                }
        }


        public void setSelectedIndex(int i) {
                this.mSelectedIndex = i;
        }
}

Questo è tutto dovrei lavorare sul onDrawerItemChange?

Grazie ancora per il vostro aiuto.