Layout do coordenador com barra de ferramentas em fragmentos ou atividade


94

Com a nova biblioteca de design, há vários novos layouts que mudam muito a forma como a barra de ferramentas pode se comportar se o desenvolvedor assim desejar. Uma vez que fragmentos diferentes têm comportamentos e objetivos diferentes, por exemplo, um fragmento de galeria com uma barra de ferramentas recolhida mostrando uma foto importante, ou um fragmento sem uma visualização de rolagem que simplesmente não precisa do appbarlayout para ocultar a barra de ferramentas, ter uma única barra de ferramentas na atividade pode provar difícil.

Com isso, devo mover a barra de ferramentas para cada fragmento? Nesse caso, tenho que definir o supportActionBar cada vez que mostrar um fragmento e também ter uma referência da atividade no fragmento que anula a natureza independente dos fragmentos. Se eu deixar a barra de ferramentas sozinha na Activity, tenho que ter vários layouts definidos para cada tipo de comportamento em cada fragmento. Qual seria a melhor abordagem?


1
Olá, você encontrou uma solução?
SERG

2
para o meu projeto atual, decidi ficar com a barra de ferramentas na Activity e fazer as animações adequadas quando necessário. Mas é um pouco complicado. Tentei usar a barra de ferramentas em cada fragmento e funcionou bem, mas animar a barra de ferramentas entre as transições de fragmentos é mais difícil e nem sei se é possível porque não tenho muita experiência com animações de transições de fragmentos.
mobilepotato7

alguma atualização ou solução melhor para isso agora?
Sagar Nayak

Respostas:


56

Para mim, parece muito estranho ter appbar e barra de ferramentas em cada fragmento. Portanto, optei por ter uma única barra de aplicativos com barra de ferramentas em atividade.

Para resolver esse problema com o CoordinatorLayout, você terá que definir um comportamento diferente do seu FrameLayout(ou de qualquer outro Layout) que deveria conter fragmentos de cada fragmento que você deseja substituir o comportamento padrão.

Vamos supor que seu comportamento padrão seja app:layout_behavior="@string/appbar_scrolling_view_behavior"

Então, em seu fragment_activity_layout.xml você pode ter algo assim:

<android.support.design.widget.CoordinatorLayout
    android:id="@+id/coordinator"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.design.widget.AppBarLayout
        android:id="@+id/appbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <android.support.v7.widget.Toolbar
            android:id="@+id/dashboard_toolbar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:theme="@style/AppTheme.Toolbar"
            app:layout_scrollFlags="scroll|enterAlways"/>
    </android.support.design.widget.AppBarLayout>

    <FrameLayout
        android:id="@+id/dashboard_content"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
</android.support.design.widget.CoordinatorLayout>

E em cada fragmento que você não deseja implementar, app:layout_behavior="@string/appbar_scrolling_view_behavior"você terá que substituir onAttache onDetachmétodos que irão mudar o comportamento de seu FrameLayout:

CoordinatorLayout.Behavior behavior;

@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);

    if(behavior != null)
        return;

    FrameLayout layout =(FrameLayout) getActivity().findViewById(R.id.dashboard_content);
    CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) layout.getLayoutParams();

    behavior = params.getBehavior();
    params.setBehavior(null);

}

@Override
public void onDetach() {
    super.onDetach();
    if(behavior == null)
        return;

    FrameLayout layout =(FrameLayout) getActivity().findViewById(R.id.dashboard_content);
    CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) layout.getLayoutParams();

    params.setBehavior(behavior);

    layout.setLayoutParams(params);

    behavior = null;
}

Depois disso, o CoordinatorLayout não recolherá o appbar etc. e permitirá que os layouts de fragmento tenham altura total.


Legal, vou ter que tentar isso e ver se simplifica as coisas. Obrigado.
mobilepotato7

Se você encontrar algo mais simples - me avise. Eu acho que é possível mudar o comportamento do coordenador a qualquer momento durante o ciclo de vida dos fragmentos (por exemplo, você normalmente tem uma recicladora com algumas coisas, mas em casos raros pode estar vazia e você saberá que somente após o Loader onLoadFinished, é possível que você gostaria de mostrar a imagem centralizada notificando que não há nada aqui, como no Inbox App), mas ainda não tentei. Talvez mais tarde hoje.
Клаус Шварц

Ok, isso funciona muito bem. Criei um helper que cuida de habilitar / desabilitar o coordenador quando apropriado, então eu apenas chamo enableCoordinator(Activity activity)/ disableCoordinator(Activity activity)de fragmentos.
Клаус Шварц

Onde está seu ajudante, @ КлаусШварц? Quando você liga?
santhyago

1
@santhyago no fragmento
Клаус Шварц

8

Aqui está minha solução

<!-- Put your fragment inside a Framelayout and set the behavior for this FrameLayout -->
<FrameLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior">

    <!-- Your fragment -->
    <include layout="@layout/content_main" />

</FrameLayout>

<android.support.design.widget.AppBarLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:theme="@style/AppTheme.AppBarOverlay">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="?attr/colorPrimary"
        app:layout_scrollFlags="scroll|enterAlways"
        app:popupTheme="@style/AppTheme.PopupOverlay" />

</android.support.design.widget.AppBarLayout>


1

Esta é uma pergunta muito boa: os Toolbars devem agir como um ActionBarser mantidos em um Activityou um Fragment? Depois de pesquisar diferentes questões e documentação, não consegui encontrar uma solução que abranja todos os casos. Portanto, realmente depende da sua situação e do caminho a seguir.

Caso 1: a barra de ferramentas deve ser uma substituição da ActionBar

Se a barra de ferramentas tiver que se comportar como uma ActionBar normal (ou se no máximo 1 fragmento for mostrado de vez em quando), acho que a maneira melhor / mais simples é usar a Activitiesbarra de ferramentas tradicional com sua própria barra de ferramentas e colocar seu fragmento nela. Desta forma, você não precisa se preocupar com quando qual barra de ferramentas deve ser exibida.

Alterar a ActionBar (-behaviour) de Fragments também é possível, mas eu não recomendo, já que isso força você a acompanhar qual Fragment alterou a ActionBar quando. Eu nem sei se a configuração da ActionBar pode ser feita várias vezes.

Caso 2: cada fragmento deve ter sua própria (parte da) barra de ferramentas

Você também pode optar por colocar diferentes barras de ferramentas independentes em diferentes fragmentos, com suas próprias ações. Desta forma, você pode exibir fragmentos diferentes lado a lado - cada um com suas próprias ações em sua barra de ferramentas - e sugerir que seja uma barra de ferramentas (talvez como o aplicativo do Gmail, embora eu não tenha certeza). No entanto, isso significa que você mesmo teria que inflar essas barras de ferramentas, mas não deve ser muito difícil.

Espero que isso ajude a fazer uma escolha.

(Desculpe se cometi algum erro de (idioma))


4
desculpe, mas isso realmente não responde aos problemas relativos à nova biblioteca de design. Claro, ter a barra de ferramentas como barra de ações é o objetivo, mas ter vários layouts de coordenador para diferentes tipos de barras de ferramentas pode ser complicado. O que descobri é que é possível animar a barra de ferramentas conforme necessário. Ainda preciso testá-lo melhor, mas parece que há bons resultados
mobilepotato7
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.