Ver mensagens sem resposta | Ver tópicos ativos Hoje é 14 Nov 2019, 13:03



Responder Tópico  [ 1 Mensagem ] 
 Material Design 
Autor Mensagem
Google employee
Google employee

Data de registro: 01 Jul 2013, 13:45
Mensagens: 2735
Localização: Rio de Janeiro
Mensagem Material Design
Faz algum tempo que precisei atualizar o visual de um aplicativo meu pra deixar no padrão do Material Design, então fiz um projeto pra testar essas novas funcionalidades. Não li o bastante pra dar muitas informações, mas as referências estarão no final, junto do anexo do projeto.

Primeiro, no dependencies do build.gradle da pasta app ficou assim:


dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:22.2.1'
    compile 'com.android.support:recyclerview-v7:22.2.+'
    compile 'com.android.support:cardview-v7:22.2.+'
    compile 'com.android.support:design:22.2.+'
}
 


Obs: Se estiver usando a perspectiva Android, vai ter um (Module: app) ao lado do nome do arquivo, lá na lista do Gradle Scripts.

O styles.xml que será usado está assim:


<?xml version="1.0" encoding="utf-8"?>
<resources>
    <style name="AppTheme" parent="Theme.AppCompat.NoActionBar">
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
    </style>

    <style name="FABStyle">
        <item name="android:layout_width">wrap_content</item>
        <item name="android:layout_height">wrap_content</item>
        <item name="android:layout_margin">16dp</item>
        <item name="android:src">@mipmap/ic_launcher</item>
        <item name="layout_anchorGravity">right|bottom</item>
        <item name="rippleColor">@color/colorPrimary</item>
        <item name="fabSize">normal</item>
    </style>

    <style name="ToolBarStyle">
        <item name="android:id">@id/toolbar</item>
        <item name="android:layout_width">match_parent</item>
        <item name="android:layout_height">?attr/actionBarSize</item>
    </style>

    <style name="MatchStyle">
        <item name="android:layout_width">match_parent</item>
        <item name="android:layout_height">match_parent</item>
    </style>

    <style name="WrapStyle">
        <item name="android:layout_width">wrap_content</item>
        <item name="android:layout_height">wrap_content</item>
    </style>

    <style name="MatchWrapStyle">
        <item name="android:layout_width">match_parent</item>
        <item name="android:layout_height">wrap_content</item>
    </style>

    <style name="WrapMatchStyle">
        <item name="android:layout_width">wrap_content</item>
        <item name="android:layout_height">match_parent</item>
    </style>

    <style name="HomeCardViewStyle">
        <item name="android:layout_width">match_parent</item>
        <item name="android:layout_height">150dp</item>
        <item name="cardElevation">10dp</item>
        <item name="cardBackgroundColor">@color/colorPrimaryDark</item>
        <item name="cardUseCompatPadding">true</item>
    </style>

    <style name="HomeTextViewStyle" parent="MatchWrapStyle">
        <item name="android:textColor">@color/white</item>
        <item name="android:textStyle">bold</item>
    </style>

    <style name="HomeLinearLayoutStyle" parent="MatchWrapStyle">
        <item name="android:layout_gravity">center</item>
        <item name="android:orientation">vertical</item>
    </style>
</resources>
 


Esse layout abaixo inclui um CoordinatorLayout, AppBarLayout, CollapsingToolbarLayout, ToolBar, NestedScrollView, CardView e um FloatingActionButton.

home_activity.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    style="@style/MatchStyle"
    android:background="@color/colorPrimary">


    <android.support.design.widget.AppBarLayout
        android:id="@+id/home_activity_appbar"
        style="@style/MatchWrapStyle">


        <android.support.design.widget.CollapsingToolbarLayout
            android:id="@+id/home_activity_collapsing_toolbar"
            style="@style/MatchWrapStyle"
            app:contentScrim="@color/colorPrimaryDark"
            app:layout_scrollFlags="scroll|exitUntilCollapsed">


            <LinearLayout
                style="@style/MatchWrapStyle"
                android:orientation="vertical">


                <ImageView
                    style="@style/MatchWrapStyle"
                    android:src="@mipmap/principal"/>

            </LinearLayout>

            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                app:layout_collapseMode="pin"/>

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

    <android.support.v4.widget.NestedScrollView
        style="@style/MatchStyle"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">


        <LinearLayout
            style="@style/MatchWrapStyle"
            android:orientation="vertical">


            <android.support.v7.widget.CardView
                style="@style/HomeCardViewStyle">

                <LinearLayout
                    style="@style/HomeLinearLayoutStyle">

                    <TextView
                        style="@style/HomeTextViewStyle"
                        android:text="@string/msg1"/>

                </LinearLayout>
            </android.support.v7.widget.CardView>

            <android.support.v7.widget.CardView/>

            <android.support.v7.widget.CardView/>

            <android.support.v7.widget.CardView/>
        </LinearLayout>
    </android.support.v4.widget.NestedScrollView>

    <android.support.design.widget.FloatingActionButton
        android:id="@+id/home_activity_fab"
        style="@style/FABStyle"
        app:layout_anchor="@id/home_activity_appbar"/>

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


A classe CoordinatorLayout é um container que permite um maior controle sobre os eventos de clique e animação de cada uma das suas views filhas, como elas vão se comportar em relação às outras. Por exemplo, se você deixar um FAB no inferior da tela e abrir um SnackBar, o FAB vai subir junto e voltar ao lugar quando o SnackBar sumir, ao invés de ficar por atrás dele. Mais pra frente terá um SnackBar em uso.

AppBarLayout é um LinearLayout vertical que implementa que implementa recursos de rolagem no material design. As views que estiverem nele devem definir seu comportamento desejado usando o atributo app:layout_scrollFlags. Ela depende do CoordinatorLayout pra funcionar corretamente, então prefiram usá-lo no lugar de um outro container.

Com o CollapsingToolbarLayout é um container pra Toolbar, onde podemos expandir ela pra mostrar uma View quando puxá-la pra baixo, sendo que até agora eu só vi aplicativos usando imagens ou videos, como a Play Store, com exceção do Google Tradutor. E note que o CollapsingToolbarLayout foi feito pra ser filho direto de AppBarLayout. O atributo app:contentScrim define a cor que a Toolbar fica quando estiver voltando ao estado inicial.

Toolbar veio pra substituir a ActionBar, e o recomendado é que esteja num arquivo xml separado, como esse abaixo:

toolbar.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/toolbar"
    android:layout_width="match_parent"
    android:layout_height="?attr/actionBarSize"
    android:background="@color/colorPrimary">

</android.support.v7.widget.Toolbar>
 


Para que ele seja inserido nos layouts, usamos um <include layout="@layout/toolbar"> em cada xml que for usar a Toolbar.
Só não o usei nesse layout porque o app:layout_collapseMode="pin" não funcionou com o include. Esse atributo com o valor pin deixa aqueles 3 pontinhos do menu no mesmo lugar, mesmo que você feche o CTL. devemos usar um theme que tenha um NoActionBar, como o Theme.AppCompat.NoActionBar, pra que a ActionBar saia e dê espaço ao Toolbar.

NestedScrollView é um como um ScrollView, mas a diferença é que que ele permite que você coloque outras views com scroll, como a ListView. O atributo app:layout_behavior ao AppBarLayout saber que deve scrolar junto ao NestedScrollView. Nesse layout, seria abrir e fechar o CollapsingToolbarLayout. Se tiver problemas com a string atributo, o valor é uma classe: android.support.design.widget.AppBarLayout$ScrollingViewBehavior.

O CardView é um container com formato de um cartão, que usa a propriedade de elevação do Lollipop pra formar uma sombra abaixo dele. Esses 3 CardViews fechados são iguais ao primeiro, diferem apenas no texto.

E tem o FloatingActionButton, que como o próprio já dá uma dica, é um botão flutuante. Bastante usada na parte inferior do layouts pra executar uma ação rápida.

Abaixo está a activity desse layout.


package br.lanzieri.materialdesigntest.activity;

import android.content.Intent;
import android.content.res.Resources;
import android.os.Bundle;
import android.support.design.widget.CollapsingToolbarLayout;
import android.support.design.widget.FloatingActionButton;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;

import br.lanzieri.materialdesigntest.R;

/**
 * Created by jeffersonlanzieri on 30/09/15.
 */

public class HomeActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.home_activity);

        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        CollapsingToolbarLayout collapsingToolbar = (CollapsingToolbarLayout) findViewById(R.id.home_activity_collapsing_toolbar);
        collapsingToolbar.setTitle("Portal Android");

        Resources res = getResources();

        collapsingToolbar.setExpandedTitleColor(res.getColor(R.color.white));
        collapsingToolbar.setCollapsedTitleTextColor(res.getColor(R.color.grey));

        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.home_activity_fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startActivity(new Intent(HomeActivity.this, TabActivity.class));
            }
        });
    }
   
    /* onCreateOptionsMenu() e onOptionsItemSelected() omitidos */
}
 


Vejam que a Toolbar está sendo usada aqui através do setSupportActionBar. Se quiser alterar alguma coisa, basta chamar o getSupportActionBar, que vai retornar um android.support.v7.app.ActionBar. A activity deve herdar de AppCompatActivity.
O setExpandedTitleColor define a cor do título quando o CTL está aberto, e o setCollapsedTitleTextColor quando fechado.
No onClick FAB uma nova activity é aberta. Seu layout é esse:


<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/tab_activity_drawerlayout"
    style="@style/MatchStyle">


    <android.support.design.widget.CoordinatorLayout
        style="@style/MatchStyle">

        <RelativeLayout
            style="@style/MatchStyle">


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

            <android.support.design.widget.TabLayout
                android:id="@+id/tab_activity_tablayout"
                style="@style/MatchWrapStyle"
                android:layout_below="@+id/toolbar"
                android:background="@color/colorPrimary">

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

            <android.support.v4.view.ViewPager
                android:id="@+id/tab_activity_viewpager"
                style="@style/MatchStyle"
                android:layout_below="@id/tab_activity_tablayout">

            </android.support.v4.view.ViewPager>
        </RelativeLayout>
    </android.support.design.widget.CoordinatorLayout>

    <android.support.design.widget.NavigationView
        android:id="@+id/tab_activity_navigation_view"
        style="@style/MatchStyle"
        android:layout_gravity="left"
        android:background="@color/colorPrimary"
        app:menu="@menu/navigation_menu">

    </android.support.design.widget.NavigationView>
</android.support.v4.widget.DrawerLayout>
 


Pra quem não conhece, o DrawerLayout serve pra colocar um menu escondido numa das laterais da tela.
O TabLayout é um HorizontalScrollView que provê um layout em forma de abas (classe TabLayout.Tab).
Com o NavigationView, ótimo pra usar em conjunto com o DrawerLayout, ter esse menu fica bem mais fácil porque ele pode ser populado por um menu xml, com o app:menu. Também é possível usar um layout normal, será mostrado numa outra activity.


package br.lanzieri.materialdesigntest.activity;

import android.os.Bundle;
import android.support.design.widget.NavigationView;
import android.support.design.widget.TabLayout;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.view.ViewPager;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.Gravity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MenuItem.OnMenuItemClickListener;

import br.lanzieri.materialdesigntest.R;
import br.lanzieri.materialdesigntest.adapter.ViewPagerAdapter;

/**
 * Created by jeffersonlanzieri on 02/10/15.
 */

public class TabActivity extends AppCompatActivity implements OnMenuItemClickListener {
    private DrawerLayout drawerLayout;
    private ViewPager viewPager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.tab_activity);

        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        drawerLayout = (DrawerLayout) findViewById(R.id.tab_activity_drawerlayout);

        TabLayout tabLayout = (TabLayout) findViewById(R.id.tab_activity_tablayout);

        viewPager = (ViewPager) findViewById(R.id.tab_activity_viewpager);
        viewPager.setAdapter(new ViewPagerAdapter(getSupportFragmentManager()));

        tabLayout.setupWithViewPager(viewPager);

        NavigationView navigationView = (NavigationView) findViewById(R.id.tab_activity_navigation_view);
        Menu menu = navigationView.getMenu();

        menu.findItem(R.id.navigation_menu_fragment1).setOnMenuItemClickListener(this);
        menu.findItem(R.id.navigation_menu_fragment2).setOnMenuItemClickListener(this);
        menu.findItem(R.id.navigation_menu_fragment3).setOnMenuItemClickListener(this);
    }

    @Override
    public boolean onMenuItemClick(MenuItem item) {
        int position = 0;

        switch (item.getItemId()) {
            case R.id.navigation_menu_fragment1:
                position = 0;
                break;
            case R.id.navigation_menu_fragment2:
                position = 1;
                break;
            case R.id.navigation_menu_fragment3:
                position = 2;
                break;
        }
        viewPager.setCurrentItem(position);
        drawerLayout.closeDrawer(Gravity.LEFT);
        return false;
    }
}
 


Aqui o TabLayout é populado com os dados do ViewPager pelo setupWithViewPager, mas pra adicionar de modo normal use um Tab tab = tabLayout.newTab(); e ir setando os valores.
Do NavigationView eu só peguei cada item do menu pra setar um listener neles.

O adapter e seus fragments:


package br.lanzieri.materialdesigntest.adapter;

import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;

import br.lanzieri.materialdesigntest.fragment.FormularyFragment;
import br.lanzieri.materialdesigntest.fragment.RecyclerFragment;
import br.lanzieri.materialdesigntest.fragment.RecyclerFragment.TypeLayout;

/**
 * Created by jeffersonlanzieri on 05/10/15.
 */

public class ViewPagerAdapter extends FragmentStatePagerAdapter {

    @Override
    public int getCount() {
        return 3;
    }

    @Override
    public Fragment getItem(int position) {
        Fragment fragment = null;

        switch (position) {
            case 0:
                fragment = new FormularyFragment();
                break;
            case 1:
                fragment = new RecyclerFragment(TypeLayout.LINEAR);
                break;
            case 2:
                fragment = new RecyclerFragment(TypeLayout.GRID);
                break;
        }
        return fragment;
    }

    @Override
    public CharSequence getPageTitle(int position) {
        String title = null;

        switch (position) {
            case 0:
                title = "TextInputLayout";
                break;
            case 1:
                title = "RecyclerView Linear";
                break;
            case 2:
                title = "RecyclerView Grid";
                break;
        }
        return title;
    }

    public ViewPagerAdapter(FragmentManager fm) {
        super(fm);
    }
}
 



package br.lanzieri.materialdesigntest.fragment;

import android.os.Bundle;
import android.support.design.widget.TextInputLayout;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;

import br.lanzieri.materialdesigntest.R;

/**
 * Created by jeffersonlanzieri on 02/10/15.
 */

public class FormularyFragment extends Fragment implements View.OnClickListener {
    private TextInputLayout til;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View root = inflater.inflate(R.layout.formulary_fragment, container, false);

        til = (TextInputLayout) root.findViewById(R.id.formulary_fragment_til);

        Button button = (Button) root.findViewById(R.id.formulary_fragment_button);
        button.setOnClickListener(this);

        return root;
    }

    @Override
    public void onClick(View v) {
        int len = til.getEditText().length();

        if (len <= 3) {
            til.setError("Tá errado!");
        }
    }
}
 


O layout desse fragment é o formulary_fragment.xml, com esse conteúdo:


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    style="@style/MatchStyle"
    android:orientation="vertical"
    android:background="@color/white">


    <android.support.design.widget.TextInputLayout
        android:id="@+id/formulary_fragment_til"
        style="@style/MatchWrapStyle">

        <EditText
            style="@style/MatchWrapStyle"
            android:hint="@string/hint_username"
            android:textColorHint="@color/colorPrimaryDark"
            android:textColor="@color/colorPrimaryDark"
            android:singleLine="true">

        </EditText>
    </android.support.design.widget.TextInputLayout>

    <android.support.design.widget.TextInputLayout
        style="@style/MatchWrapStyle">

        <EditText
            style="@style/MatchWrapStyle"
            android:hint="@string/hint_email"
            android:textColorHint="@color/colorPrimaryDark"
            android:textColor="@color/colorPrimaryDark"
            android:singleLine="true">

        </EditText>
    </android.support.design.widget.TextInputLayout>

    <android.support.design.widget.TextInputLayout
        style="@style/MatchWrapStyle">

        <EditText
            style="@style/MatchWrapStyle"
            android:hint="@string/hint_password"
            android:textColorHint="@color/colorPrimaryDark"
            android:textColor="@color/colorPrimaryDark"
            android:singleLine="true">

        </EditText>
    </android.support.design.widget.TextInputLayout>

    <Button
        android:id="@+id/formulary_fragment_button"
        style="@style/MatchWrapStyle"
        android:text="@string/send">

    </Button>
</LinearLayout>
 


Esse TextInputLayout é um container pro EditText que mostra o hint num texto flutuante, assim quando você começar a escrever o texto do hint vai continuar visível. O texto só vai subir/flutuar quando o EditText estiver com o foco ou preenchido.

formulary_fragment.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    style="@style/MatchStyle">


    <android.support.v7.widget.RecyclerView
        android:id="@+id/recycler_fragment_recyclerview"
        style="@style/MatchStyle">

    </android.support.v7.widget.RecyclerView>

    <android.support.design.widget.FloatingActionButton
        android:id="@+id/recycler_fragment_fab"
        style="@style/FABStyle"
        app:layout_anchor="@id/recycler_fragment_recyclerview">

    </android.support.design.widget.FloatingActionButton>
</android.support.design.widget.CoordinatorLayout>
 



package br.lanzieri.materialdesigntest.fragment;

import android.content.Intent;
import android.content.res.Resources;
import android.graphics.Rect;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.v4.app.Fragment;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.RecyclerView.Adapter;
import android.support.v7.widget.RecyclerView.LayoutManager;
import android.support.v7.widget.RecyclerView.State;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;

import br.lanzieri.materialdesigntest.R;
import br.lanzieri.materialdesigntest.activity.AnyActivity;
import br.lanzieri.materialdesigntest.adapter.GridAdapter;
import br.lanzieri.materialdesigntest.adapter.LinearAdapter;
import br.lanzieri.materialdesigntest.model.Distro;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by jeffersonlanzieri on 02/10/15.
 */

public class RecyclerFragment extends Fragment {
    private TypeLayout type;

    public static enum TypeLayout {
        GRID, LINEAR
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View root = inflater.inflate(R.layout.recycler_fragment, container, false);

        RecyclerView recycler = (RecyclerView) root.findViewById(R.id.recycler_fragment_recyclerview);

        FloatingActionButton fab = (FloatingActionButton) root.findViewById(R.id.recycler_fragment_fab);
        fab.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent i = new Intent(getActivity(), AnyActivity.class);
                startActivity(i);
            }
        });

        List<Distro> list = new ArrayList<>();
        Resources res = getActivity().getResources();

        int iconSize = 37;

        for (int i = 0; i < iconSize; i++) {
            String nameRes = "distro" + (i + 1);
            int iconRes = res.getIdentifier(nameRes, "mipmap", getActivity().getPackageName());

            list.add(new Distro(iconRes, nameRes + ".png"));
        }

        Adapter adapter = null;
        LayoutManager manager = null;

        switch (type) {
            case GRID:
                adapter = new GridAdapter(list);
                manager = new GridLayoutManager(getActivity(), 3);
                break;
            case LINEAR:
                adapter = new LinearAdapter(list);
                manager = new LinearLayoutManager(getActivity());
                break;
        }
        recycler.setLayoutManager(manager);
        recycler.setAdapter(adapter);
        recycler.addItemDecoration(new MarginDecoration());

        return root;
    }

    public RecyclerFragment(TypeLayout type) {
        this.type = type;
    }

    private class MarginDecoration extends RecyclerView.ItemDecoration {
        @Override
        public void getItemOffsets(Rect outRect, View view, RecyclerView parent, State state) {
            int margin = 2;
            outRect.set(margin, margin, margin, margin);
        }
    }
}
 


RecyclerView pode ser considerado um sucessor da ListView, mas não significa que extende dela. Você pode ter uma lista ou grid comum, com rolagem na vertical ou horizontal se quiser, mas precisa definir o LayoutManager pra funcionar. E algo muito bom está em seu adapter, que já implementa o padrão ViewHolder. Eu estou usando 2 adapters, um pra mostrar em grid e outro é linear, como a ListView comum. Nessa classe MarginDecoration eu deixo um pequeno espaço entre cada item do RecyclerView.

linear_item.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    style="@style/MatchStyle"
    android:background="@drawable/item_selector">


    <ImageView
        android:id="@+id/linear_item_imageview"
        style="@style/WrapStyle"
        android:paddingLeft="3dp"
        android:layout_alignParentLeft="true">

    </ImageView>

    <TextView
        android:id="@+id/linear_item_textview"
        style="@style/WrapStyle"
        android:paddingRight="4dp"
        android:layout_alignParentRight="true"
        android:layout_alignParentBottom="true"
        android:textSize="20dp"
        android:textStyle="bold"
        android:textColor="@color/black">

    </TextView>
</RelativeLayout>
 



package br.lanzieri.materialdesigntest.adapter;

import android.graphics.Color;
import android.support.design.widget.Snackbar;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import br.lanzieri.materialdesigntest.R;
import br.lanzieri.materialdesigntest.model.Distro;

import java.util.List;

/**
 * Created by jeffersonlanzieri on 05/10/15.
 */

public class LinearAdapter extends RecyclerView.Adapter<LinearAdapter.DistroHolder> {
    private List<Distro> list;

    @Override
    public DistroHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.linear_item, parent, false);
        return new DistroHolder(view);
    }

    @Override
    public void onBindViewHolder(final DistroHolder holder, final int position) {
        final Distro distro = list.get(position);

        holder.icon.setImageResource(distro.getIconId());
        holder.title.setText(distro.getName());

        holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar snack = Snackbar.make(view, distro.getName(), Snackbar.LENGTH_SHORT);
                snack.setAction("Mostrar Toast", new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        Toast.makeText(v.getContext(), "SnackBar Pressionado", Toast.LENGTH_SHORT).show();
                    }
                });
                snack.setActionTextColor(Color.GREEN);
                snack.show();
            }
        });
    }

    @Override
    public int getItemCount() {
        return list.size();
    }

    public LinearAdapter(List<Distro> list) {
        this.list = list;
    }

    public static class DistroHolder extends RecyclerView.ViewHolder {
        private ImageView icon;
        private TextView title;

        public DistroHolder(View itemView) {
            super(itemView);
            icon = (ImageView) itemView.findViewById(R.id.linear_item_imageview);
            title = (TextView) itemView.findViewById(R.id.linear_item_textview);
        }
    }
}
 


Os 3 métodos desse adapter são obrigatórios. O onCreateViewHolder retorna um ViewHolder e o getItemCount a quantidade de itens do adapter. É no onBindViewHolder que os dados de cada item são definidos. Pra ter acesso ao objeto View, usamos usamos a variável itemView do ViewHolder no parâmetro do método. O SnackBar é uma pequena mensagem que aparece no inferior da tela, que serve pra dar algum aviso ou outra informação qualquer. A classe Distro é um model simples com os atributos desses gets ali em cima.
A classe GridAdapter é igual à LinearAdapter, exceto pela ausência do TextView. O layout é esse:

grid_item.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    style="@style/MatchStyle"
    android:background="@drawable/item_selector">


    <ImageView
        android:id="@+id/grid_item_imageview"
        style="@style/WrapStyle"
        android:layout_margin="5dp">

    </ImageView>
</RelativeLayout>
 


Pra terminar, a classe AnyActivity, que vai ter um NavigationView populado com um layout xml.


package br.lanzieri.materialdesigntest.activity;

import android.os.Bundle;
import android.support.design.widget.NavigationView;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.CardView;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

import br.lanzieri.materialdesigntest.R;

public class AnyActivity extends AppCompatActivity implements View.OnClickListener {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.any_activity);

        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        NavigationView navigation = (NavigationView) findViewById(R.id.any_activity_navigationview);

        CardView cardView = (CardView) navigation.findViewById(R.id.navigation_layout_cardview);
        cardView.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        Toast.makeText(this, "Clicou no CardView", Toast.LENGTH_SHORT).show();
    }

    public void showDistroName(View view) {
        String text = ((Button) view).getText().toString();
        Toast.makeText(this, text, Toast.LENGTH_SHORT).show();
    }
}
 


Pra pegar as views no NavigationView usamos o findViewById dele.


any_activity.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    style="@style/MatchStyle"
    android:background="@color/colorPrimaryDark"
    android:orientation="vertical">


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

    <android.support.v4.widget.DrawerLayout
        style="@style/MatchStyle">


        <TextView
            style="@style/MatchStyle"
            android:text="@string/description">

        </TextView>

        <android.support.design.widget.NavigationView
            android:id="@+id/any_activity_navigationview"
            style="@style/WrapMatchStyle"
            android:layout_gravity="right"
            android:background="@color/colorPrimary"
            app:headerLayout="@layout/navigation_layout">

        </android.support.design.widget.NavigationView>
    </android.support.v4.widget.DrawerLayout>
</LinearLayout>
 


O conteúdo é definido pelo atributo app:headerLayout, que pega esse layout:


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    style="@style/MatchStyle"
    android:orientation="vertical">


    <android.support.v7.widget.CardView
        android:id="@+id/navigation_layout_cardview"
        android:layout_width="match_parent"
        android:layout_height="200dp"
        app:cardElevation="5dp"
        app:cardUseCompatPadding="true">

        <ImageView
            style="@style/MatchStyle"
            android:src="@mipmap/principal">

        </ImageView>
    </android.support.v7.widget.CardView>

    <Button
        style="@style/MatchWrapStyle"
        android:text="BigLinux"
        android:textColor="@color/white"
        android:onClick="showDistroName">

    </Button>

    <Button
        style="@style/MatchWrapStyle"
        android:text="Fedora"
        android:textColor="@color/white"
        android:onClick="showDistroName">

    </Button>

    <Button
        style="@style/MatchWrapStyle"
        android:text="OpenSuse"
        android:textColor="@color/white"
        android:onClick="showDistroName">

    </Button>

    <Button
        style="@style/MatchWrapStyle"
        android:text="Debian"
        android:textColor="@color/white"
        android:onClick="showDistroName">

    </Button>

    <Button
        style="@style/MatchWrapStyle"
        android:text="Kurumin"
        android:textColor="@color/white"
        android:onClick="showDistroName">

    </Button>

    <Button
        style="@style/MatchWrapStyle"
        android:text="Ubuntu"
        android:textColor="@color/white"
        android:onClick="showDistroName">

    </Button>
</LinearLayout>
 


Foi esse o meu projeto pra testar o material design, o anexo e os links das classes estão logo abaixo pra um melhor entendimento.

AppBarLayout
CardView
CollapsingToolbarLayout
CoordinatorLayout
DrawerLayout
FloatingActionButton
NavigationView
NestedScrollView
RecyclerView
TabLayout
TextInputLayout
Toolbar
ViewPager

viewtopic.php?f=7&t=24174
http://developer.android.com/intl/pt-br ... index.html
http://developer.android.com/intl/pt-br ... arted.html

Anexo:
MaterialDesignTest.7z


Você não tem permissões suficientes para ver os arquivos anexados nesta mensagem.

_________________
Quando seu problema for resolvido, clique na opção Editar no lado superior direito da sua primeira mensagem e coloque [Resolvido] no título.
Se resolveu o problema sozinh@, não esqueça de postar a solução, ela ajuda usuários em buscas no fórum.
Use os marcadores java e xml quando for postar.

Aprenda Java com esta apostila.


26 Nov 2015, 22:37
Perfil WWW
Mostrar mensagens anteriores:  Organizar por  
Responder Tópico   [ 1 Mensagem ] 

Quem está online

Usuários vendo este fórum: adolfo, agtavares, alex.abrantes, alexandrefett, allart, allone, andreluiz, b7web, beeshop, billsombrio, BornSlip, breko, canaville, carminati, cassiano, Celso Jr., compto, czambroni, DaDih*, dannieltec, deborazb, diemesleno, Douglas Siviotti, DroidBot, edlinux, edsonel, EduardoYC, eferrari, epsilva, erosvaldo, estratecnologia, fabiano_eletro, fabricioLeonard, fabrizior, felipedsilva, flaviocc, fraga, francismarconcini, Gabriel Teófilo, gamito, gapler, geeks, Geire Robson Gadelha, Gnomo, henrikesilva1, henrique.cardoso, henrique.garcia, ICCrawler - ICjobs, ice, jacard, jacksaum, jacksonvpj, jackstuard, Jless@, jonasminas, juliana_costa, juliherms, Juliobcosta, juniorsk8, Juniorvs, jwv, jzaires, kleberperea, kpinheiro, lalaine, laucode, Legiao, leo, leofernandesmo, Leonardo333, Lord, lucasmadeira, lucianno, luizcyber, marcelosv, marciosoliveira, marianatallas, masf_33, Maxtremus, mayahaslinger, Mayron Cimardi, memnoch, Microdesk, mikasjau, MpassosT, neimarguerra, neosun, nsansilva, o-raposa, osternack, Padawan, paulabr, paulo.esantos, paulokiller, peixe, pgbatera, Philipe Alves, rafael.winter, rafaelvital, renegheller, rguadagnini, ricardo_listadelphi, robsonoracle, rodrigosalfer, ronanPlus, Roney dos Santos, rotmeil, rsl_master, rubens_olv, samuel.cavanieri, SEO Crawler, Shaman286, Shmi Skywalker, SidneiCP, skcratch, thiaguim, tiagocomerio, tirloni, tonylock, Vector, waideman, Wds, wesley.messias, wil, WiseNut, Wookiees, Wryel, zaquiel e 2 visitantes


Você não pode criar novos tópicos neste fórum
Você não pode responder tópicos neste fórum
Você não pode editar suas mensagens neste fórum
Você não pode excluir suas mensagens neste fórum
Você não pode enviar anexos neste fórum

Procurar por:

© 2007 - 2016 Portal Android - Comunidade de Desenvolvedores Android

Estamos no Linkedin    Siga-nos no twitter


Powered by phpBB - Hospedado por Bemobi