Showing posts with label Relative Layout. Show all posts
Showing posts with label Relative Layout. Show all posts

Wednesday, 15 March 2017

HB Blog 131: Material Design For Registration - Login Module.

Registration and login has been most important and very first step in a mobile application. There are various ways through which we can achieve these functionality. Not only functionality wise but also applications look and feel is very important. While Android and other mobile application users increasing, we are moving more over towards UI/UX interfaces. Android has been using material design in various patterns.

In these tutorial, I will show how to use material design for login and registration screens.

We need single page application which uses proper animations for screen transitions and provide easy to use and understand way. Using these sample code use can easily design registration-login module.


Refer the below link for complete sample code:-

Download Sample Code

Have a look on few code snippets,

//MainActivity.java 
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
import android.app.ActivityOptions;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.v4.app.ActivityOptionsCompat;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.CardView;
import android.transition.Explode;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

import butterknife.ButterKnife;
import butterknife.InjectView;
import butterknife.OnClick;

public class MainActivity extends AppCompatActivity {

    @InjectView(R.id.et_username)
    EditText etUsername;
    @InjectView(R.id.et_password)
    EditText etPassword;
    @InjectView(R.id.bt_go)
    Button btGo;
    @InjectView(R.id.cv)
    CardView cv;
    @InjectView(R.id.fab)
    FloatingActionButton fab;

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

    }

    @OnClick({R.id.bt_go, R.id.fab})
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.fab:
                getWindow().setExitTransition(null);
                getWindow().setEnterTransition(null);

                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                    ActivityOptions options =
                            ActivityOptions.makeSceneTransitionAnimation(this, fab, fab.getTransitionName());
                    startActivity(new Intent(this, RegisterActivity.class), options.toBundle());
                } else {
                    startActivity(new Intent(this, RegisterActivity.class));
                }
                break;
            case R.id.bt_go:
                Explode explode = new Explode();
                explode.setDuration(500);

                getWindow().setExitTransition(explode);
                getWindow().setEnterTransition(explode);
                ActivityOptionsCompat oc2 = ActivityOptionsCompat.makeSceneTransitionAnimation(this);
                Intent i2 = new Intent(this,LoginSuccessActivity.class);
                startActivity(i2, oc2.toBundle());
                break;
        }
    }
}

//RegisterActivity.java 
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.graphics.Color;
import android.os.Build;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.CardView;
import android.transition.Transition;
import android.transition.TransitionInflater;
import android.view.View;
import android.view.ViewAnimationUtils;
import android.view.animation.AccelerateInterpolator;

import butterknife.ButterKnife;
import butterknife.InjectView;

public class RegisterActivity extends AppCompatActivity {

    @InjectView(R.id.fab)
    FloatingActionButton fab;
    @InjectView(R.id.cv_add)
    CardView cvAdd;

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

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            ShowEnterAnimation();
        }
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                animateRevealClose();
            }
        });
    }

    private void ShowEnterAnimation() {
        Transition transition = TransitionInflater.from(this).inflateTransition(R.transition.fabtransition);
        getWindow().setSharedElementEnterTransition(transition);

        transition.addListener(new Transition.TransitionListener() {
            @Override
            public void onTransitionStart(Transition transition) {
                cvAdd.setVisibility(View.GONE);
            }

            @Override
            public void onTransitionEnd(Transition transition) {
                transition.removeListener(this);
                animateRevealShow();
            }

            @Override
            public void onTransitionCancel(Transition transition) {

            }

            @Override
            public void onTransitionPause(Transition transition) {

            }

            @Override
            public void onTransitionResume(Transition transition) {

            }


        });
    }

    public void animateRevealShow() {
        Animator mAnimator = ViewAnimationUtils.createCircularReveal(cvAdd, cvAdd.getWidth()/2,0, fab.getWidth() / 2, cvAdd.getHeight());
        mAnimator.setDuration(500);
        mAnimator.setInterpolator(new AccelerateInterpolator());
        mAnimator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                super.onAnimationEnd(animation);
            }

            @Override
            public void onAnimationStart(Animator animation) {
                cvAdd.setVisibility(View.VISIBLE);
                super.onAnimationStart(animation);
            }
        });
        mAnimator.start();
    }

    public void animateRevealClose() {
        Animator mAnimator = ViewAnimationUtils.createCircularReveal(cvAdd,cvAdd.getWidth()/2,0, cvAdd.getHeight(), fab.getWidth() / 2);
        mAnimator.setDuration(500);
        mAnimator.setInterpolator(new AccelerateInterpolator());
        mAnimator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                cvAdd.setVisibility(View.INVISIBLE);
                super.onAnimationEnd(animation);
                fab.setImageResource(R.drawable.plus);
                RegisterActivity.super.onBackPressed();
            }

            @Override
            public void onAnimationStart(Animator animation) {
                super.onAnimationStart(animation);
            }
        });
        mAnimator.start();
    }
    @Override
    public void onBackPressed() {
        animateRevealClose();
    }
}

//activity_main.xml 
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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:background="@drawable/bg"
    tools:context="cn.fanrunqi.materiallogin.MainActivity">

    <android.support.v7.widget.CardView
        android:layout_width="300dp"
        android:layout_height="300dp"
        app:cardCornerRadius="6dp"
        app:cardElevation="3dp"
        app:cardUseCompatPadding="true"
        android:layout_centerInParent="true"
        android:id="@+id/cv">
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical"
            >
        <RelativeLayout
            android:layout_marginTop="10dp"
            android:layout_width="match_parent"
            android:layout_height="45dp">
            <View
                android:layout_alignParentStart="true"
                android:layout_width="8dp"
                android:layout_height="match_parent"
                android:background="#2fa881"
                />
            <TextView
                android:layout_centerVertical="true"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginStart="50dp"
                android:text="@string/login"
                android:textColor="#FFCC00"
                android:textSize="18sp"
                android:textStyle="bold"
                />
        </RelativeLayout>
        <LinearLayout
            android:layout_marginTop="10dp"
            android:paddingStart="50dp"
            android:paddingEnd="30dp"
            android:orientation="horizontal"
            android:layout_width="match_parent"
            android:layout_height="50dp">
            <android.support.design.widget.TextInputLayout
                android:textColorHint="#c5c5c5"
                android:layout_width="match_parent"
                android:layout_height="wrap_content">
                <EditText
                    android:textSize="13sp"
                    android:hint="@string/Username"
                    android:textColor="#2fa881"
                    android:id="@+id/et_username"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:inputType="textPersonName"
                    android:background="@drawable/selector_bg_edit"
                    android:textCursorDrawable="@drawable/bg_input_cursor"
                    android:paddingBottom="2dp"
                    />
            </android.support.design.widget.TextInputLayout>
        </LinearLayout>
            <LinearLayout
                android:paddingStart="50dp"
                android:paddingEnd="30dp"
                android:orientation="horizontal"
                android:layout_width="match_parent"
                android:layout_height="50dp">
                <android.support.design.widget.TextInputLayout
                    android:textColorHint="#c5c5c5"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content">
                    <EditText
                        android:textSize="13sp"
                        android:hint="@string/Password"
                        android:textColor="#2fa881"
                        android:id="@+id/et_password"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:inputType="textPassword"
                        android:background="@drawable/selector_bg_edit"
                        android:textCursorDrawable="@drawable/bg_input_cursor"
                        android:paddingBottom="2dp"
                        />
                </android.support.design.widget.TextInputLayout>
            </LinearLayout>
            <RelativeLayout
                android:layout_marginTop="25dp"
                android:gravity="center"
                android:layout_width="match_parent"
                android:layout_height="60dp">
                <Button
                    android:id="@+id/bt_go"
                    android:background="@drawable/bt_shape"
                    android:stateListAnimator="@drawable/state_list_animator_z"
                    android:layout_width="150dp"
                    android:layout_height="50dp"
                    android:text="@string/go"
                    android:textColor="#d3d3d3"
                    >
                </Button>
            </RelativeLayout>
            <TextView
                android:layout_marginTop="5dp"
                android:layout_gravity="center_horizontal"
                android:textColor="#9a9a9a"
                android:textSize="12sp"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@string/forgot_your_password"
                />
        </LinearLayout>
        </android.support.v7.widget.CardView>

    <android.support.design.widget.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:fabSize="normal"
        android:src="@drawable/plus"
        android:transitionName="loginFab"
        android:layout_alignTop="@id/cv"
        android:layout_marginTop="25dp"
        android:layout_alignEnd="@id/cv"
        android:layout_marginEnd="-20dp"
        />

</RelativeLayout>

//activity_register.xml 
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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:background="@drawable/bg">

    <android.support.v7.widget.CardView
        android:layout_width="300dp"
        android:layout_height="300dp"
        app:cardCornerRadius="6dp"
        app:cardElevation="3dp"
        app:cardUseCompatPadding="true"
        android:layout_centerInParent="true"
        android:id="@+id/cv">
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical"
            >
        <RelativeLayout
            android:layout_marginTop="10dp"
            android:layout_width="match_parent"
            android:layout_height="45dp">
            <View
                android:layout_alignParentStart="true"
                android:layout_width="8dp"
                android:layout_height="match_parent"
                android:background="#2fa881"
                />
            <TextView
                android:layout_centerVertical="true"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginStart="50dp"
                android:text="@string/login"
                android:textColor="#FFCC00"
                android:textSize="18sp"
                android:textStyle="bold"
                />
        </RelativeLayout>
        <LinearLayout
            android:layout_marginTop="10dp"
            android:paddingStart="50dp"
            android:paddingEnd="30dp"
            android:orientation="horizontal"
            android:layout_width="match_parent"
            android:layout_height="50dp">
            <android.support.design.widget.TextInputLayout
                android:textColorHint="#c5c5c5"
                android:layout_width="match_parent"
                android:layout_height="wrap_content">
                <EditText
                    android:textSize="13sp"
                    android:hint="@string/Username"
                    android:textColor="#2fa881"
                    android:id="@+id/et_username"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:inputType="textPersonName"
                    android:background="@drawable/selector_bg_edit"
                    android:textCursorDrawable="@drawable/bg_input_cursor"
                    android:paddingBottom="2dp"
                    />
            </android.support.design.widget.TextInputLayout>
        </LinearLayout>
            <LinearLayout
                android:paddingStart="50dp"
                android:paddingEnd="30dp"
                android:orientation="horizontal"
                android:layout_width="match_parent"
                android:layout_height="50dp">
                <android.support.design.widget.TextInputLayout
                    android:textColorHint="#c5c5c5"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content">
                    <EditText
                        android:textSize="13sp"
                        android:hint="@string/Password"
                        android:textColor="#2fa881"
                        android:id="@+id/et_password"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:inputType="textPassword"
                        android:background="@drawable/selector_bg_edit"
                        android:textCursorDrawable="@drawable/bg_input_cursor"
                        android:paddingBottom="2dp"
                        />
                </android.support.design.widget.TextInputLayout>
            </LinearLayout>
            <RelativeLayout
                android:layout_marginTop="25dp"
                android:gravity="center"
                android:layout_width="match_parent"
                android:layout_height="60dp">
                <Button
                    android:id="@+id/bt_go"
                    android:background="@drawable/bt_shape"
                    android:stateListAnimator="@drawable/state_list_animator_z"
                    android:layout_width="150dp"
                    android:layout_height="50dp"
                    android:text="@string/go"
                    android:textColor="#d3d3d3"
                    >
                </Button>
            </RelativeLayout>
            <TextView
                android:layout_marginTop="5dp"
                android:layout_gravity="center_horizontal"
                android:textColor="#9a9a9a"
                android:textSize="12sp"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@string/forgot_your_password"
                />
        </LinearLayout>
        </android.support.v7.widget.CardView>

    <android.support.design.widget.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:fabSize="normal"
        android:src="@drawable/plus"
        android:transitionName="loginFab"
        android:layout_alignTop="@id/cv"
        android:layout_marginTop="25dp"
        android:layout_alignEnd="@id/cv"
        android:layout_marginEnd="-20dp"
        />

</RelativeLayout>

Wednesday, 22 July 2015

HB Blog 84: Comparing Android's Relative Layout With iOS Auto Layout.

I have been working on iOS's auto layout for a while and as an Android developer I found auto layout concept pretty similar to Android's relative layout. Both concept go with one single moto to arrange views or components with respect to other views or components depending on devices.

Arranging views on the screen:-
In Android, we have below examples of layouts to arrange views on the screen.
LinearLayout:-
It is a view group that aligns all children in a single direction, vertically or horizontally. You can specify the layout direction with the android:orientation attribute.
RelativeLayout:-
It is a view group that displays child views in relative positions. The position of each view can be specified as relative to sibling elements (such as to the left-of or below another view) or in positions relative to the parent RelativeLayout area (such as aligned to the bottom, left or center).

In iOS, we have concept of auto layout to arrange views on the screen.
Auto Layout:- 
It is a system that lets you lay out your app’s user interface by creating a mathematical description of the relationships between the elements. You define these relationships in terms of constraints either on individual elements, or between sets of elements. Using Auto Layout, you can create a dynamic and versatile interface that responds appropriately to changes in screen size, device orientation, and localization.

Basically, both Android as well as iOS prefer MVC(model-view-controller) pattern, and both use xml for view creation. The main theory behind arranging views on screen is to satisfy the view or component height, width, x and y co - ordinates.

Height and width of a view:-
In Android, we have layout params that describes how big the view wants to be for both width and height. The base LayoutParams class just describes how big the view wants to be for both width and height.
 For each dimension, it can specify one of:
    FILL_PARENT (renamed MATCH_PARENT in API Level 8 and higher), which means that the view wants to be as big as its parent (minus padding)
    WRAP_CONTENT, which means that the view wants to be just big enough to enclose its content (plus padding)
    an exact number

There are subclasses of LayoutParams for different subclasses of ViewGroup. For example, AbsoluteLayout has its own subclass of LayoutParams which adds an X and Y value.

In iOS, we have height and width constraints for each view. We can also use equal width and equal height constraint to make view width and height dependable equally on another view.

Now, for the main job is to satisfy x and y of a view.
In Android, linear layout aligns all children in a single direction, vertically or horizontally but, it is not efficient to create complex UI. So we have relative layout, where the positions of the children can be described in relation to each other or to the parent specified by ID.So you can align two elements by right border, or make one below another, centered in the screen, centered left, and so on. By default, all child views are drawn at the top-left of the layout. There are various properties that are available for the views inside relative layout.
  android:layout_alignParentTop
    If "true", makes the top edge of this view match the top edge of the parent.
android:layout_centerVertical
    If "true", centers this child vertically within its parent.
android:layout_below
    Positions the top edge of this view below the view specified with a resource ID.
android:layout_toRightOf

 Positions the left edge of this view to the right of the view specified with a resource ID.
In iOS, we have constraint to satisfy x and y of a view. An attribute is one of left, right, top, bottom, leading, trailing, width, height, centerX, centerY, and baseline. Leading and trailing defines the view to its left and right position with respect to the superview or adjacent view. The constraints such as left, right, top, bottom,etc specify respective position on adjacent view.
Comparing Android relative layout properties with iOS auto layout constraints:-
  1. The height and width of both views inside relative layout or views using auto layout are same.
  2. The auto layout constraint leading space & trailingspace are similar to relative layout properties android:layout_alignParentLeft="true" & android:layout_alignParentRight="true" to arrange view with respect to parent's edge whereas, android:layout_toLeftOf & android:layout_toRightOf with respect to child's edge.
  3. The auto layout constraint top space & bottom space are similar to relative layout properties android:layout_alignParentTop="true" & android:layout_alignParentBottom="true" to arrange view with respect to parent's edge.
  4. The auto layout constraint center horizontal space & center vertical space are similar to relative layout properties android:layout_centerHorizontal & android:layout_centerVertical to arrange view horizontally or vertically with respect to the bounds of its RelativeLayout parent.
  5. The auto layout constraint horizontal space & vertical space are similar to relative layout properties  android:layout_toLeftOf  & android:layout_below to arrange view at position respective to the given anchor view ID.