Showing posts with label Snackbar. Show all posts
Showing posts with label Snackbar. Show all posts

Tuesday, March 1, 2016

Snackbar: The appropriate interruption

A Snackbar is similar to a Toast, but is more versatile in that it is interactive — like offering that undo your user is still searching for. A Snackbar animates upward from the bottom of the screen and the user can swipe it away — or not. If they do nothing, it will time out on its own and automatically disappear (like a Toast!).


Read the blog post: https://medium.com/@dontmesswithjo/snackbar-the-appropriate-interruption-ceb54d9be583

Alerts are pretty critical for communicating with your user. But it helps to know what is appropriate so that your users don’t hate you. Fortunately, there’s a simple answer: use a Snackbar! (http://developer.android.com/reference/android/support/design/widget/Snackbar.html)

But, for those nuanced cases where you want to choose between a Toast and a Snackbar, the design docs have pretty much every detail you could need. (http://www.google.com/design/spec/components/snackbars-toasts.html#) And if you really like being wrong, there’s always a Dialog! (http://www.google.com/design/spec/components/dialogs.html#dialogs-behavior)

But you’re better than that. So be a better developer and use the better choice: Snackbar.


Related:
- My blog post of "Android Snackbar example of Android Design Support Library".

Thursday, October 1, 2015

Hello World to open photo using Intent.ACTION_OPEN_DOCUMENT, with FloatingActionButton and Snackbar

This example work on last post "Updated Android Studio now provide template of Blank Activity with FloatingActionButton and Snackbar", modify the default Hello World to open image with ACTION_OPEN_DOCUMENT,  display on ImageView.


edit layout/activity_main.xml, to modify the icon of the FloatingActionButton, android:src inside <android.support.design.widget.FloatingActionButton>.
<?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"
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
    android:layout_height="match_parent" android:fitsSystemWindows="true"
    tools:context=".MainActivity">

    <android.support.design.widget.AppBarLayout android:layout_height="wrap_content"
        android:layout_width="match_parent" 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:popupTheme="@style/AppTheme.PopupOverlay" />

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

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

    <android.support.design.widget.FloatingActionButton android:id="@+id/fab"
        android:layout_width="wrap_content" android:layout_height="wrap_content"
        android:layout_gravity="bottom|end" android:layout_margin="@dimen/fab_margin"
        android:src="@android:drawable/ic_menu_gallery" />

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


layout/content_main.xml, it's the main layout of our app.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="16dp"
    android:orientation="vertical"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:showIn="@layout/activity_main"
    tools:context=".MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="20dp"
        android:layout_gravity="center_horizontal"
        android:autoLink="web"
        android:text="http://android-er.blogspot.com/"
        android:textStyle="bold"/>

    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">

            <TextView
                android:id="@+id/texturi"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content" />
            <ImageView
                android:id="@+id/image"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:adjustViewBounds="true"/>

        </LinearLayout>
    </ScrollView>
</LinearLayout>


com.blogspot.android_er.androidhello.MainActivity.java
package com.blogspot.android_er.androidhello;

import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageView;
import android.widget.TextView;

import java.io.FileNotFoundException;

public class MainActivity extends AppCompatActivity {

    private static final int RQS_OPEN_IMAGE = 1;

    ImageView imageView;
    TextView textUri;

    Bitmap bmOriginal = null;
    Uri targetUri = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Open photo", Snackbar.LENGTH_LONG)
                        .setAction("OK", snackbarOnClickListener)
                        .show();
            }
        });

        textUri = (TextView) findViewById(R.id.texturi);
        imageView = (ImageView) findViewById(R.id.image);
    }

    OnClickListener snackbarOnClickListener = new OnClickListener(){
        @Override
        public void onClick(View v) {

            bmOriginal = null;
            imageView.setImageBitmap(null);

            Intent intent = new Intent();

            if (Build.VERSION.SDK_INT >=
                    Build.VERSION_CODES.KITKAT) {
                intent.setAction(Intent.ACTION_OPEN_DOCUMENT);
            } else {
                intent.setAction(Intent.ACTION_GET_CONTENT);
            }

            intent.addCategory(Intent.CATEGORY_OPENABLE);

            // set MIME type for image
            intent.setType("image/*");

            startActivityForResult(intent, RQS_OPEN_IMAGE);

        }
    };

    @TargetApi(Build.VERSION_CODES.KITKAT)
    @Override
    protected void onActivityResult(int requestCode,
                                    int resultCode, Intent data) {

        if (resultCode == Activity.RESULT_OK) {

            Uri dataUri = data.getData();

            if (requestCode == RQS_OPEN_IMAGE) {
                targetUri = dataUri;
                textUri.setText(dataUri.toString());
                updatImage(dataUri);
            }
        }

    }

    private void updatImage(Uri uri){

        if (uri != null){
            Bitmap bm;
            try {
                bm = BitmapFactory.decodeStream(
                        getContentResolver()
                                .openInputStream(uri));
                imageView.setImageBitmap(bm);
                bmOriginal = bm;

            } catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

}



download filesDownload the files (Android Studio Format) .

Related:
- Using Intent.ACTION_OPEN_DOCUMENT, for KitKat API 19 or higher

Next:
Apply photo effects using Media Effects APIs

Updated Android Studio now provide template of Blank Activity with FloatingActionButton and Snackbar




Related:
- Modify this Hello World to open image using Intent.ACTION_OPEN_DOCUMENT, with FloatingActionButton and Snackbar.
Disable FloatingActionButton


Monday, August 10, 2015

Set text and background color of Snackbar

Example to show how to set text and background color of Snackbar.


Keep using layout/activity_main.xml in last example "CoordinatorLayout + FloatingActionButton + Snackbar of Android Design Support Library".

com.example.eric.androidfloatingactionbutton.MainActivity.java
package com.example.eric.androidfloatingactionbutton;

import android.graphics.Color;
import android.support.design.widget.CoordinatorLayout;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    FloatingActionButton floatingActionButton1, floatingActionButton2;
    CoordinatorLayout coordinatorLayout;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        coordinatorLayout = (CoordinatorLayout)findViewById(R.id.coordinatorLayout);
        floatingActionButton1 =
                (FloatingActionButton)findViewById(R.id.floatingActionButton1);
        floatingActionButton2 =
                (FloatingActionButton)findViewById(R.id.floatingActionButton2);

        floatingActionButton1.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v) {

                Snackbar snackbar = Snackbar.make(
                        coordinatorLayout,
                        "Snackbar: floatingActionButton1 (normal) clicked",
                        Snackbar.LENGTH_LONG);
                snackbar.setActionTextColor(Color.RED);
                View snackbarView = snackbar.getView();
                snackbarView.setBackgroundColor(Color.WHITE);
                TextView textView = (TextView) snackbarView.findViewById(android.support.design.R.id.snackbar_text);
                textView.setTextColor(Color.BLUE);

                snackbar.setAction("OK", new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        Toast.makeText(
                                MainActivity.this,
                                "snackbar OK clicked",
                                Toast.LENGTH_LONG).show();
                    }
                });

                snackbar.show();
            }
        });

        floatingActionButton2.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v) {
                Snackbar.make(
                        coordinatorLayout,
                        "Snackbar: floatingActionButton2 (mini) clicked",
                        Snackbar.LENGTH_LONG)
                        .setActionTextColor(0xFFFF0000)
                        .setAction("OK", new View.OnClickListener() {
                            @Override
                            public void onClick(View v) {
                                Toast.makeText(
                                    MainActivity.this,
                                    "snackbar OK clicked",
                                    Toast.LENGTH_LONG).show();}
                            })
                        .show();


            }
        });
    }

}



CoordinatorLayout + FloatingActionButton + Snackbar of Android Design Support Library

This example show how CoordinatorLayout + FloatingActionButton + Snackbar work together - a FloatingActionButton added as a child of CoordinatorLayout, and then pass that CoordinatorLayout to Snackbar.make() call - instead of the snackbar displaying over the floating action button, the FloatingActionButton takes advantage of additional callbacks provided by CoordinatorLayout to automatically move upward as the snackbar animates in and returns to its position when the snackbar animates out on Android 3.0 and higher devices - no extra code required.


layout/activity_main.xml
<android.support.design.widget.CoordinatorLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_margin="20dp"
    android:padding="10dp"
    android:id="@+id/coordinatorLayout"
    android:background="#000050"
    tools:context=".MainActivity">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_margin="20dp"
        android:padding="10dp"
        android:background="#005000">

        <TextView
            android:id="@+id/title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:autoLink="web"
            android:textSize="24dp"
            android:layout_alignParentTop="true"
            android:text="http://android-er.blogspot.com/"
            android:textStyle="bold" />

        <TextView
            android:id="@+id/textView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textStyle="bold"
            android:textSize="30dp"
            android:layout_alignParentBottom="true"
            android:text="Android FloatingActionButton example" />
    </RelativeLayout>

    <android.support.design.widget.FloatingActionButton
        android:id="@+id/floatingActionButton1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="20dp"
        android:layout_marginRight="20dp"
        android:src="@mipmap/ic_launcher"
        app:fabSize="normal"
        app:layout_anchor="@id/coordinatorLayout"
        app:layout_anchorGravity="bottom|left|end"/>

    <android.support.design.widget.FloatingActionButton
        android:id="@+id/floatingActionButton2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="20dp"
        android:layout_marginRight="20dp"
        android:src="@mipmap/ic_launcher"
        app:fabSize="mini"
        app:layout_anchor="@id/coordinatorLayout"
        app:layout_anchorGravity="bottom|right|end"/>

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


com.example.eric.androidfloatingactionbutton.MainActivity.java
package com.example.eric.androidfloatingactionbutton;

import android.support.design.widget.CoordinatorLayout;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    FloatingActionButton floatingActionButton1, floatingActionButton2;
    CoordinatorLayout coordinatorLayout;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        coordinatorLayout = (CoordinatorLayout)findViewById(R.id.coordinatorLayout);
        floatingActionButton1 =
                (FloatingActionButton)findViewById(R.id.floatingActionButton1);
        floatingActionButton2 =
                (FloatingActionButton)findViewById(R.id.floatingActionButton2);

        floatingActionButton1.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v) {

                Snackbar snackbar = Snackbar.make(
                        coordinatorLayout,
                        "Snackbar: floatingActionButton1 (normal) clicked",
                        Snackbar.LENGTH_LONG);

                snackbar.setAction("OK", new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        Toast.makeText(
                                MainActivity.this,
                                "snackbar OK clicked",
                                Toast.LENGTH_LONG).show();
                    }
                });

                snackbar.show();
            }
        });

        floatingActionButton2.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v) {
                Snackbar snackbar = Snackbar.make(
                        coordinatorLayout,
                        "Snackbar: floatingActionButton2 (mini) clicked",
                        Snackbar.LENGTH_LONG);

                snackbar.setAction("OK", new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        Toast.makeText(
                                MainActivity.this,
                                "snackbar OK clicked",
                                Toast.LENGTH_LONG).show();
                    }
                });

                snackbar.show();
            }
        });
    }

}


Android Design Support Library is needed, read "How to Add Android Design Support Library to Android Studio Project".


Next:
Set text and background color of Snackbar

Friday, August 7, 2015

Android Snackbar example of Android Design Support Library

android.support.design.widget.Snackbar provide lightweight feedback about an operation. They show a brief message at the bottom of the screen on mobile and lower left on larger devices. Snackbars appear above all other elements on screen and only one can be displayed at a time.

They automatically disappear after a timeout or after user interaction elsewhere on the screen, particularly after interactions that summon a new surface or activity. Snackbars can be swiped off screen.


- Make sure your main activity extends AppCompatActivity.
- Make sure include dependencies of both 'com.android.support:appcompat-v7:22.2.1' and 'com.android.support:design:22.2.1' (currently version 22.2.1) in your build.gradle. Refer last post about how to "Add Android Design Support Library to Android Studio Project".


- Add <android.support.design.widget.CoordinatorLayout> in your layout file, layout/activity_main.xml.
<LinearLayout
    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:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:autoLink="web"
        android:text="http://android-er.blogspot.com/"
        android:textStyle="bold" />

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textStyle="bold"
        android:textSize="30dp"
        android:text="Android Snackbar example" />

    <Button
        android:id="@+id/showSnackBar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Show SnackBar" />

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

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

</LinearLayout>


com.example.eric.snackbar.MainActivity.java
package com.example.eric.snackbar;

import android.os.Bundle;
import android.support.design.widget.CoordinatorLayout;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    Button btnShowSnackBar;
    CoordinatorLayout snackbarCoordinatorLayout;

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

        snackbarCoordinatorLayout = (CoordinatorLayout)findViewById(R.id.snackbarCoordinatorLayout);

        btnShowSnackBar = (Button)findViewById(R.id.showSnackBar);
        btnShowSnackBar.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v) {
                Snackbar snackbar = Snackbar.make(
                        snackbarCoordinatorLayout,
                        "Snackbar",
                        Snackbar.LENGTH_LONG);

                snackbar.setAction("OK", new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        Toast.makeText(
                                MainActivity.this,
                                "snackbar OK clicked",
                                Toast.LENGTH_LONG).show();
                    }
                });

                snackbar.show();
            }

        });
    }

}