Sunday 15 October 2017

HB Blog 146: Create Product Counter Used In Android Applications.

In programming world we have very much importance of time and delivery of the product. We need to keep building up pieces so that we can build up complete product in time.
Here, in this tutorial I will show how to create counter that we have seen in many shopping cart and online food delivery Android applications such as Flipkart, Amazon, Zomato, etc.
Refer the below link for complete sample code:-

Download Sample Code

Have a look on few code snippets,

//custom_counter.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
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:orientation="vertical">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:gravity="center"
        android:orientation="horizontal">
        <ImageView
            android:id="@+id/ib_counterminus"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/ic_minus" />
        <EditText
            android:id="@+id/et_countervalue"
            android:layout_width="100dp"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:digits="0123456789"
            android:gravity="center"
            android:imeOptions="actionDone"
            android:inputType="number"
            android:singleLine="true" />
        <ImageView
            android:id="@+id/ib_counterplus"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/ic_plus" />
    </LinearLayout>
</LinearLayout>

//activity_main.xml
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
<?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">

    <com.harshalbenake.counterview.views.CustomCounter
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true" />
</RelativeLayout>

//CustomCounter.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
121
122
123
124
125
126
127
128
129
130
131
package com.harshalbenake.counterview.views;

import android.content.Context;
import android.text.method.DigitsKeyListener;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.view.View;
import android.view.inputmethod.EditorInfo;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.harshalbenake.counterview.R;

/**
 * This class is used for custom counter.
 */
public class CustomCounter extends LinearLayout implements View.OnClickListener,TextView.OnEditorActionListener {
    private Context mContext;
    private EditText met_countervalue;

    public interface OnConterSubmitListner {
        void onConterSubmit();
    }

    OnConterSubmitListner mOnConterSubmitListner;


    public CustomCounter(Context context) {
        super(context);
        this.mContext = context;
        initlayout();
    }

    public CustomCounter(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.mContext = context;
        initlayout();
    }

    public CustomCounter(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        this.mContext = context;
        initlayout();
    }

    /**
     * initialize Layout
     */
    private void initlayout() {
        View rootView = inflate(mContext, R.layout.custom_counter, this);
        met_countervalue = (EditText) rootView.findViewById(R.id.et_countervalue);
        ImageView ib_counterminus = (ImageView) rootView.findViewById(R.id.ib_counterminus);
        ImageView ib_counterplus = (ImageView) rootView.findViewById(R.id.ib_counterplus);

        ib_counterminus.setOnClickListener(this);
        ib_counterplus.setOnClickListener(this);
        met_countervalue.setOnEditorActionListener(this);

        met_countervalue.setKeyListener(DigitsKeyListener.getInstance(true,true));

    }

    @Override
    public void onClick(View view) {
        int viewId = view.getId();
        if (viewId == R.id.ib_counterminus) {
            decrementValue();
        } else if (viewId == R.id.ib_counterplus) {
            incrementValue();
        }
    }

    @Override
    public boolean onEditorAction(TextView textView, int actionId, KeyEvent keyEvent) {
        if (actionId == EditorInfo.IME_ACTION_DONE) {
            if (mOnConterSubmitListner != null) {
                mOnConterSubmitListner.onConterSubmit();
            }
        }
        return false;
    }

    /**
     * increments Value
     */
    private void incrementValue() {
        int counterValue = getValue();
        met_countervalue.setText(String.valueOf(counterValue + 1));
    }

    /**
     * decrements Value
     */
    private void decrementValue() {
        int counterValue = getValue();
        if (counterValue > 0) {
            met_countervalue.setText(String.valueOf(counterValue - 1));
        }
    }

    /**
     * gets Value
     */
    public int getValue() {
        String counterValue = met_countervalue.getText().toString().trim();
        if (counterValue!=null && !counterValue.equalsIgnoreCase("")) {
            return Integer.valueOf(counterValue);
        } else {
            return 0;
        }
    }

    /**
     * sets Value
     */
    public void setValue(String strValue) {
        if (strValue!=null && !strValue.equalsIgnoreCase("")) {
            met_countervalue.setText(Integer.valueOf(strValue)+"");
        }
    }

    /**
     * set On ConterSubmit Listner
     * @param onConterSubmitListner
     */
    public void setOnConterSubmitListner(OnConterSubmitListner onConterSubmitListner) {
        mOnConterSubmitListner = onConterSubmitListner;
    }
}

Sunday 1 October 2017

HB Blog 145: Autofill Framework In Andriod O.

Earlier, mobiles were just used for calling and messaging purposes but, now a days mobile technology has been developed such a way that it can do all human based daily tasks. Banking and similar offices were having lot of problems with forms and paper works which has been digitized now thanks to mobile technologies.
We are moving from single screen to multi-screens applications. But, still applications such as banking, etc. have forms which are tired-sum to fill for users.
Android Oreo has new feature called 'Autofill Framework' that can help in solving these problems. Users can save time filling out forms by using autofill in their devices. Android makes filling forms, such as account and credit card forms, easier with the introduction of the Autofill Framework. The Autofill Framework manages the communication between the app and an autofill service.

The Autofill Framework improves the user experience by providing the following benefits:
  •     Less time spent in filling fields Autofill saves users from re-typing information.
  •     Minimize user input errors Typing is prone to errors, especially in mobile devices. Removing the necessity of typing information also removes the errors that come with it.
Before apps can work with the Autofill Framework, an autofill service must be enabled in the system settings. Users can enable or disable autofill as well as change the autofill service in Settings > System > Languages & input > Advanced > Input assistance > Autofill service. An autofill service can require the user to authenticate before the autofill data can be used to complete fields in your app.

Optimizing your app for autofill:-
Apps that use standard views work with the Autofill Framework out of the box. However, you can take some steps to optimize how your app works with the framework.
Ensuring data is available -
In some special cases, you need to take additional steps to make sure that the data is available to the Autofill Framework to save. In this case, the data in the original layout is not available to the framework. To make the data available to the framework, you should call commit() on the AutofillManager object before replacing the original layout.
Providing hints for autofill - Typically, there is just one way to autofill a view, but there could be multiple ways if the view accepts more than one type of information. For example, a view used to identify the user might accept either a username or an email address. These hints can be set using either the android:autofillHints attribute or the setAutofillHints() method.
Mark fields as important for autofill - You can tell the system whether the individual fields in your app should be included in a view structure for autofill purposes. You can use the setImportantForAutofill() method, passing the mode, to determine if the view is important for autofill.

Associate website and mobile app data:-
You can associate your Android app with your website to let other services know that user data, such as login credentials, can be shared between these environments. Autofill services can take advantage of this association if they provide services on a browser and on Android. For example, if users choose the same autofill service in both environments, they can sign-in to a website using a browser, and the login credentials are available to autofill when the same users try to sign-in to the associated app on Android.