Now you can Subscribe using RSS

Submit your Email

Monday

Rounded corners in ImageView Android Tutorial/Example

Vishal Shrestha





As it's clear from the title already, in this post we will discuss how we can display round corners in an ImageView. There can be several ways to show rounded corners, some of the ones I have tried are:
  • Using a library like this one: Rounded ImageView Library
  • Create a CardView with required corner radius and put ImageView inside it.
  • Add rounding to the image itself.
In this post we will do everything our-self because, a: It's ease and b: We can. ;)
So let get started:

Here's the screenshot of rounded corner effect we will create as a result of this example:

Image-with-round-corner-in-ImageView
Round Corner in ImageView

How to Round the corners of an Image

Let's first understand how we will be rounding the corners the Image. It just requires two steps
  1. First we will draw a rectangle on a canvas with the required roundness of corners.
  2. Then we will draw the required Bitmap on the canvas with the PorterDuff.Mode.SRC_IN mode set in the paint. You are probably confused about PorterDuff, I was too. It's basically a way to merge different images with each other where different images are on different layers similar to Photoshop. Below is the image of different PorterDuff modes. You can read more about it here: PorterDuff Modes:
  3. Porter-Duff-Mode-used-for-rounding-corners-in-imageView
    Porter Duff Modes
  4. You are done! Just return the new Bitmap created by step 1 and 2 and display it in ImageView.
The Code for Rounding the corners of Image.

1. activity_main.xml
This is simple we just two ImageViews where we will add images after the corner of the image has been rounded.

<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:gravity="center"
    android:orientation="vertical"
    android:padding="@dimen/activity_horizontal_margin"
    tools:context=".MainActivity">

    <ImageView
        android:id="@+id/imageView1"
        android:layout_width="246dp"
        android:layout_height="246dp" />

    <ImageView
        android:id="@+id/imageView2"
        android:layout_width="246dp"
        android:layout_height="246dp" />

</LinearLayout>


2. ImageConverter.java
This is the meat of the code.  The getRoundedCornerBitmap method takes the Bitmap and the required rounded of corners as parameter and returns new Bitmap with round corners. I've comment all the main parts of the code should be self explanatory.

package com.vysh.corneredimage;

import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;

public class ImageConverter {
public static Bitmap getRoundedCornerBitmap(Bitmap bitmap, int pixels) {

        //Setting the width and height of the Bitmap that will be returned                        //equal to the original Bitmap that needs round corners.
        Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);

        //Creating canvas with output Bitmap for drawing
        Canvas canvas = new Canvas(output);

        //Setting paint and rectangles.
        final int color = Color.BLACK;
        final Paint paint = new Paint();
        final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
        final RectF rectF = new RectF(rect);
        final float roundPx = pixels;

        paint.setAntiAlias(true);
        canvas.drawARGB(0, 0, 0, 0);
        paint.setColor(color);
        canvas.drawRoundRect(rectF, roundPx, roundPx, paint);

        //SetXfermode applies PorterDuffXfermode to paint.
        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));

        canvas.drawBitmap(bitmap, rect, rect, paint);

        return output;
    }
}

3. MainActivity.java
We have everything ready, now we just need the use our ImageConverter class's getRoundedCornerBitmap Method and apply the returned Bitmap as ImageView's background and we are done!

package com.vysh.corneredimage;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.ImageView;

public class MainActivity extends AppCompatActivity {

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

        iv1 = (ImageView)findViewById(R.id.imageView1);
        iv2 = (ImageView)findViewById(R.id.imageView2);

        Bitmap bitmap1 = BitmapFactory.decodeResource(this.getResources(),R.drawable.img1);
        Bitmap circularBitmap1 = ImageConverter.getRoundedCornerBitmap(bitmap1, 100);
        Bitmap bitmap2 = BitmapFactory.decodeResource(this.getResources(),R.drawable.img2);
        Bitmap circularBitmap2 = ImageConverter.getRoundedCornerBitmap(bitmap2, 100);

        iv1.setImageBitmap(circularBitmap1);
        iv2.setImageBitmap(circularBitmap2);
    }

}

Voila! now you have finally created Images with round corner. If you have any questions, feel free to comment below. Happy Coding.

Source code: Rounded Corners in ImageView Example

Saturday

Complete Braintree Android Integration Tutorial.

Vishal Shrestha







In this post we will completely integrate Braintree payment in an Android app. We will also create our own PHP server side scripts to fully understand the functioning. If you are not familiar with PHP you don't need to worry, we will just create two PHP methods and it's fairly simple, you will understand it in no time. You can download the full source code at the bottom of this post.
Let's first discuss how Braintree Payments in an App works. There are two parts to it:
1. The Client Side (Android App)
2. The Server Side.

Let's first discuss the client side, the client side includes the following steps:

Braintree-integration-android-client-side
Client Side for Braintree Integration. (Pic Courtesy: Braintree)
  1. Our app requests the token from Server. 
  2. The server generates a token using Braintree's SDK and sends it back to the android app). 
  3. The app then gets the user's credit card info and then contacts the Braintree server to receive a payment nonce.
  4. After the app receives the payment nonce from the Braintree server, it will contact our own server with payment amount and Nonce. (The server then handles payment and has to send information to the app whether the payment was successful of not)
Now in the server side, we do the following tasks:
Braintree integration in Android app server side (Pic courtesy: Braintree)

  1. The server receives token request from the client (Our Android app).
  2. Server generates the token and sends back the token to app.
  3. (Step 4 in image above)The server receives the payment details and nonce from the client app.
  4. (Step 5 in image above)Our server contacts the Braintree server with Nonce and get response if the payment was successful or not.
Now that we have understood how the payment process works, let's start with some actual coding, first let's do the client side.

Steps to Integrate Braintree Payment in Android App (Client Side). 



First of all, let's add dependencies for using Braintree. We will also add dependency for using Volley using which we will create API requests. Add the dependencies in app level Gradle file as shown below. Dependencies are :


          compile 'com.braintreepayments.api:drop-in:3.+
     compile 'com.android.volley:volley:1.0.0'

Braintree-dependency-for-Android-integration

Now let's create layout for the app, we have a simple layout with an EditText where the user will enter the amount to pay and a button to make the payment.

Braintree-android-integration

Here's the code for the layout main_activity.xml.


<?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="match_parent"
    android:gravity="center"
    android:orientation="vertical"
    android:padding="16dp">


    <LinearLayout
        android:id="@+id/llHolder"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:orientation="vertical"
        android:visibility="gone">

        <TextView
            android:id="@+id/tvMessage"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:text="Ready for transaction"
            android:textSize="18sp"
            android:textStyle="bold" />

        <android.support.design.widget.TextInputLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="16dp">

            <EditText
                android:id="@+id/etPrice"
                android:layout_width="match_parent"
                android:inputType="text"
                android:imeOptions="actionDone"
                android:layout_height="wrap_content"
                android:gravity="center"
                android:hint="Choose the amount to pay" />

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

        <Button
            android:id="@+id/btnPay"
            android:layout_width="148dp"
            android:layout_height="wrap_content"
            android:layout_marginTop="16dp"
            android:background="@color/colorPrimaryDark"
            android:text="Pay"
            android:textColor="@android:color/white" />
    </LinearLayout>

</LinearLayout>



Notice that we've added visibility:gone in our nested linear layout as we first want to get the token from server, only then we want to show form to user to make payments as we need token for payments and we cannot make payments through Braintree without tokens. Once we get the token, we set its visibility to visible.

Now we will create the MainActivity.java. Here's the code for it:
Note: As we have not created APIs yet for getting token, we will leave that variable empty for now. After we create APIs we will add our API.
Steps in this Activity:
  1. We first call our API that will get the client token using an Async class(API is created at the end of this post).
  2. Once we've successfully got the client token, we can use that to make payments using Braintree. So we set the visibility of the form to Visibile so that user can enter the amount to pay.
  3. Once user click's the pay button, we present user a DropInForm. DropInForm is Braintree's default form where user need to enter their credit card details. It's Braintree's default implementation to get user card data. Once the user enters his/her details, the details are directly sent to Braintree's server and the server returns a Nonce to the app.
  4. Once the Nonce is received from the Braintree server, we send the Nonce along with the amount that user has entered in the 2nd step to our own server using an API that we'll create in the end of this post.
  5. Finally we receive reply from our server regarding the payment.

public class MainActivity extends AppCompatActivity {

    final int REQUEST_CODE = 1;
    final String get_token = "YOUR-API-TO-GET-TOKEN";
    final String send_payment_details = "YOUR-API-FOR-PAYMENTS";
    String token, amount;
    HashMap<String, String> paramHash;

    Button btnPay;
    EditText etAmount;
    LinearLayout llHolder;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main_activity);
        llHolder = (LinearLayout) findViewById(R.id.llHolder);
        etAmount = (EditText) findViewById(R.id.etPrice);
        btnPay = (Button) findViewById(R.id.btnPay);
        btnPay.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                onBraintreeSubmit();
            }
        });
        new HttpRequest().execute();
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == REQUEST_CODE) {
            if (resultCode == Activity.RESULT_OK) {
                DropInResult result = data.getParcelableExtra(DropInResult.EXTRA_DROP_IN_RESULT);
                PaymentMethodNonce nonce = result.getPaymentMethodNonce();
                String stringNonce = nonce.getNonce();
                Log.d("mylog", "Result: " + stringNonce);
                // Send payment price with the nonce
                // use the result to update your UI and send the payment method nonce to your server
                if (!etAmount.getText().toString().isEmpty()) {
                    amount = etAmount.getText().toString();
                    paramHash = new HashMap<>();
                    paramHash.put("amount", amount);
                    paramHash.put("nonce", stringNonce);
                    sendPaymentDetails();
                } else
                    Toast.makeText(MainActivity.this, "Please enter a valid amount.", Toast.LENGTH_SHORT).show();

            } else if (resultCode == Activity.RESULT_CANCELED) {
                // the user canceled
                Log.d("mylog", "user canceled");
            } else {
                // handle errors here, an exception may be available in
                Exception error = (Exception) data.getSerializableExtra(DropInActivity.EXTRA_ERROR);
                Log.d("mylog", "Error : " + error.toString());
            }
        }
    }

    public void onBraintreeSubmit() {
        DropInRequest dropInRequest = new DropInRequest()
                .clientToken(token);
        startActivityForResult(dropInRequest.getIntent(this), REQUEST_CODE);
    }

    private void sendPaymentDetails() {
        RequestQueue queue = Volley.newRequestQueue(MainActivity.this);
        // Request a string response from the provided URL.
        StringRequest stringRequest = new StringRequest(Request.Method.POST, send_payment_details,
                new Response.Listener<String>() {
                    @Override
                    public void onResponse(String response) {
                        if(response.contains("Successful"))
                        {
                            Toast.makeText(MainActivity.this, "Transaction successful", Toast.LENGTH_LONG).show();
                        }
                        else Toast.makeText(MainActivity.this, "Transaction failed", Toast.LENGTH_LONG).show();
                        Log.d("mylog", "Final Response: " + response.toString());
                    }
                }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                Log.d("mylog", "Volley error : " + error.toString());
            }
        }) {
            @Override
            protected Map<String, String> getParams() {
                if (paramHash == null)
                    return null;
                Map<String, String> params = new HashMap<>();
                for (String key : paramHash.keySet()) {
                    params.put(key, paramHash.get(key));
                    Log.d("mylog", "Key : " + key + " Value : " + paramHash.get(key));
                }

                return params;
            }

            @Override
            public Map<String, String> getHeaders() throws AuthFailureError {
                Map<String, String> params = new HashMap<>();
                params.put("Content-Type", "application/x-www-form-urlencoded");
                return params;
            }
        };
        queue.add(stringRequest);
    }

    private class HttpRequest extends AsyncTask {
        ProgressDialog progress;

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            progress = new ProgressDialog(MainActivity.this, android.R.style.Theme_DeviceDefault_Dialog);
            progress.setCancelable(false);
            progress.setMessage("We are contacting our servers for token, Please wait");
            progress.setTitle("Getting token");
            progress.show();
        }

        @Override
        protected Object doInBackground(Object[] objects) {
            HttpClient client = new HttpClient();
            client.get(get_token, new HttpResponseCallback() {
                @Override
                public void success(String responseBody) {
                    Log.d("mylog", responseBody);
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            Toast.makeText(MainActivity.this, "Successfully got token", Toast.LENGTH_SHORT).show();
                            llHolder.setVisibility(View.VISIBLE);
                        }
                    });
                    token = responseBody;
                }

                @Override
                public void failure(Exception exception) {
                    final Exception ex = exception;
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            Toast.makeText(MainActivity.this, "Failed to get token: " + ex.toString(), Toast.LENGTH_LONG).show();
                        }
                    });
                }
            });
            return null;
        }

        @Override
        protected void onPostExecute(Object o) {
            super.onPostExecute(o);
            progress.dismiss();
        }
    }
}

Steps to Integrate Braintree Payment in Android App (Server Side - PHP). 

Getting Braintree API Key Credentials:

To get started with back-end first we need to create a Braintree account. Go to Braintree and create a new account if you don't have one already, then login to the Braintree control panel. Then hover over account on top navigation bar and click on my user. You will see a page similar to this. Then click on view right next to the public key.

Braintree-API-Key-Credentials-for-android

Once you clicked on view you will see a page similar to this, select PHP as the language above the details that are provided. You will need these details in the next step.

Braintree-API-Key-Credentials

Server Side coding in PHP: 


Steps involved in server side development:
Note: I've used  XAMPP for server side functionality. The following will assume you have installed XAMPP.
  1. Download Braintree's PHP SDK, I do it using composer.
  2. Create API for sending token.
  3. Create API for receiving payment details and sending Braintree server's reply.
Let's use composer for downloading Braintree's PHP SDK. Download composer from here: Composer.
After downloading, install composer. Create a folder inside C:\xampp\htdocs. I've named it BraintreePayments. Now create a composer.json file in your root directory (BraintreePayments). Copy this inside the file.

{
  "require" : {
    "braintree/braintree_php" : "3.23.0"
  }
}

Once you copied and saved the code above inside composer.json, Open the terminal in your root directory(Directory with composer.json) and execute composer install. It will download Braintree's PHP SDK and you will finally be ready to code API for you Andoird App. Once everything is finished. Create a new folder inside BraintreePayments, name it include and create a new file braintree_init.php inside it. Copy the following code in it, these are just your API credentials that you will need:


<?php
session_start();
require_once("vendor/autoload.php");
if(file_exists(__DIR__ . "/../.env")) {
    $dotenv = new Dotenv\Dotenv(__DIR__ . "/../");
    $dotenv->load();
}
Braintree_Configuration::environment('sandbox');
Braintree_Configuration::merchantId('YOUR-MERCHAND-IT');
Braintree_Configuration::publicKey('YOUR-PUBLIC-KEY');
Braintree_Configuration::privateKey('YOUR-PRIVATE-KEY');
?>
Check the step above this one to check how to get you API credentials. Once your saved this file, go back to the root directory. Create a new file, call it main.php and write the following code in it:

<?php
require_once ("include/braintree_init.php");
require_once 'vendor/braintree/braintree_php/lib/Braintree.php';
echo ($clientToken = Braintree_ClientToken::generate());
?>


This code simply echos (Displays) the clientToken, but when we call this file from our Android Device we will receive this token and we can use it further for contacting Braintree's server.

After main.php is ready, create a new file name it checkout.php. This file will deal with getting payment amount and Nonce from the client and sending it to the Braintree server. It will receive the reply from Braintree server and we can take steps accordingly.  In this example, we don't parse the reply from server. We will straight away send the response to our App and if it contains the text successful, we will toast payments was successful, or else, payment failed.
Here's the code for checkout.php:
<?php
require_once ("include/braintree_init.php");
require_once 'vendor/braintree/braintree_php/lib/Braintree.php';

$nonce = $_POST['nonce'];
$amount = $_POST['amount'];
$result = Braintree_Transaction::sale([
  'amount' => $amount,
  'paymentMethodNonce' => $nonce,
  'options' => [
    'submitForSettlement' => True
  ]
]);
echo $result;
?>


Finally we are ready, we have created the app and we have also done the server side coding. But to use test this app we need to do one more thing, Start XAMPP and find out you ip address(Type ipconfig in terminal) and set the get_token variable that we created in the MainActivity.java to http://YOURIP/YOUR-ROOT-FOLDER/main.php and set send_payment_details variable to http://YOURIP/YOUR-ROOT-FOLDER/checkout.php. Bravo, we done it. Now build and test you app!

Download full Android app with Braintree Integration: BraintreePayments
Server Side Code: BraintreePaymentsServer.
In case you are wondering what the Braintree's server replies to our server, here's what it looks like, in actual production this needs to be properly parsed by the server, but we are just sending it to our Android app and if it contains the word successful, we show a toast message as Payment successful.

Braintree-reply-for-android-app

Sunday

RecyclerView with GridLayoutManager Android Tutorial with Example

Vishal Shrestha








Today we will be making a Grid View like list using a RecyclerView with GridLayoutManager as shown in the Video below, but let's first talk a little bit about recyclerView; as you might already know a RecyclerView is more advanced, flexible and efficient version of a ListView. If you have large datasets, you should work with RecyclerView instead of ListView for better efficiency and performance. How it does that? Putting simply, recyclerView just uses the views that have been inflated for a row again for new data when needed instead of inflating new views again. RecylerView needs to use LayoutManager that manage measuring and positioning views inside a recyclerView. You can watch the video below where I describe it in a bit more detail.


gridlayoutmanager recyclerview
A possibility of wWhat you can create with Grid Layout manager

So let's get started and create a RecyclerView with GridLayoutManager:

  1. First of all you need to add dependency to use RecyclerView, add this dependency in your app level gradle file:
    compile 'com.android.support:recyclerview-v7:25.3.1'

  2. After you've added the dependency, you can use recyclerView. Create a new layout, I named it main_activity.xml and add the following code in it:
    <?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="match_parent"
        android:gravity="center"
        android:orientation="vertical">

        <android.support.v7.widget.RecyclerView
            android:id="@+id/rvMain"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    </LinearLayout>


  3. Now that we have the recyclerView ready, let's create a view that will be used by the recyclerView, i.e the view that will be visible to the user as a grid in the GridView of the recyclerView. Create a new XML file and call it recycler_item or anything you want, here's the code:
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:padding="16dp"
        android:orientation="vertical">

        <ImageView
            android:id="@+id/ivLogo"
            android:layout_width="80dp"
            android:layout_height="80dp" />

        <TextView
            android:layout_margin="4dp"
            android:id="@+id/tvCompany"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />

    </LinearLayout>


  4. Now that we have our recyclerView and the grid of the recyclerView ready, we can start referencing it in java, but before all that we first need the data that we want to display in the GridView of our RecyclerView. You can download the project from the link below and find the data in strings.xml and drawable folder. After we have our data ready, create a new Java Class, MainActivity.java and write the following code in it: Note: You will get an error for now
    RecyclerView rvMain;

        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            rvMain = (RecyclerView) findViewById(R.id.rvMain);
            Bitmap[] logos = new Bitmap[12];
            logos[0] = BitmapFactory.decodeResource(getResources(), R.drawable.logo_apple);
            logos[1] = BitmapFactory.decodeResource(getResources(), R.drawable.logo_fb);
            logos[2] = BitmapFactory.decodeResource(getResources(), R.drawable.logo_google);
            logos[3] = BitmapFactory.decodeResource(getResources(), R.drawable.logo_insta);
            logos[4] = BitmapFactory.decodeResource(getResources(), R.drawable.logo_linkedin);
            logos[5] = BitmapFactory.decodeResource(getResources(), R.drawable.logo_microsoft);
            logos[6] = BitmapFactory.decodeResource(getResources(), R.drawable.logo_myspace);
            logos[7] = BitmapFactory.decodeResource(getResources(), R.drawable.logo_skype);
            logos[8] = BitmapFactory.decodeResource(getResources(), R.drawable.logo_snapchat);
            logos[9] = BitmapFactory.decodeResource(getResources(), R.drawable.logo_twitter);
            logos[10] = BitmapFactory.decodeResource(getResources(), R.drawable.logo_viber);
            logos[11] = BitmapFactory.decodeResource(getResources(), R.drawable.logo_whatsapp);
            MyAdapter adapter = new MyAdapter(getResources().getStringArray(R.array.company_list), logos);
            rvMain.setLayoutManager(new GridLayoutManager(ActivityMain.this, 2));
            rvMain.setAdapter(adapter);
        }


  5. The error you are getting in 2 of the last 3 lines is because you are using a custom adapter class but you have not created it yet. The adapter uses a view holder (I explain this in detail in the video) So let's first create a viewHolder class first, create a new class called MyViewHolder and write the following code:
    public class MyViewHolder extends RecyclerView.ViewHolder{

            public ImageView logo;
            public TextView name;

            public MyViewHolder(View itemView) {
                super(itemView);
                logo = (ImageView)itemView.findViewById(R.id.ivLogo);
                name = (TextView)itemView.findViewById(R.id.tvCompany);
            }
         }


  6. Now we have everything ready, all we need to do is create an Adapter class for our recyclerView. Create a new class called MyAdapter and write the following code in it:
    public class MyAdapter extends RecyclerView.Adapter<MyViewHolder> {

            String[] companyList;
            Bitmap[] logoList;

            public MyAdapter(String[] companyList, Bitmap[] logoList) {
                this.companyList = companyList;
                this.logoList = logoList;
            }


            @Override
            public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
                View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_item, parent, false);
                MyViewHolder viewHolder = new MyViewHolder(v);
                return viewHolder;
            }

            @Override
            public void onBindViewHolder(MyViewHolder holder, final int position) {
                holder.logo.setImageBitmap(logoList[position]);
                holder.logo.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        Toast.makeText(ActivityMain.this, "This is: " + companyList[position], Toast.LENGTH_SHORT).show();
                    }
                });
                holder.name.setText(companyList[position]);
            }

            @Override
            public int getItemCount() {
                return companyList.length;
            }
       }

Now we have our RecylerView Ready. You can now run the project and see the results, you will see a gridView like list in the recyclerView. again I recommend going through this video for learning some essential things about recyclerView. That's it for now, if you have any more questions regarding RecyclerView or GridLayoutManager feel free to drop them in the comments section below. Happy Coding! :)

SOURCE CODE DOWNLOAD LINK - RecylerView with GridLayout Manager

Monday

Set custom font in all the activities for entire application Android Tutorial

Vishal Shrestha






Everyone love a little text styling once in a while; there are various ways you can change the typeface/font of textView in your Android app, however the most simplest one is changing the typeface programmatically by applying a font to a specific textView. Although this method is simple, it requires applying the font to each textView in which you require that font. So, if you want the same font in all the Activities, you will have to provide the reference to the typeface and then apply the font manually to all the TextView, and as I am lazy, I try not to write repeated code. So in this tutorial, we will learn how to apply custom font to the TextViews in all the activities! Not only that, we will also learn how to change to font of a textView directly using XML, no java. :D
Here's the tutorial video if you prefer Videos:
 
 

Spoiler : We will do it using our own custom textView class.
In case you are want to apply custom font to only 1 textView, you can do this easily : 

Typeface my_custom_font = Typeface.createFromAsset(getAssets(), "fonts/font_name.ttf");
myTextView.setTypeface(my_custom_font);


In the code above, we refer to font_name.ttf that is inside the fonts folder in assets folder, and then we apply it to myTextView. So now the text in myTextView will have font_name.ttf font applied.

In case you prefer Videos : Set custom font in all the activities Tutorial.
Source Code : At the Bottom of the post.

Okay now let's move on to applying custom font throughout the activities.
First create a new project, give it any name. I call it theFreakyText :P .

New-custom-font-android-project
New custom font project

The next step is to choose the Minimum SDK version. It just specifies the lowest Android version that you app supports. I just chose 21 for now. You can choose lower or higher depending on your requirements.

Minimum-SDK-for-custom-font-project
Minimum SDK for custom font project

Once you've chosen the Minimum SDK version, you will see an Activity selection screen like below. You can either choose add no activity, then you need to create your own activity. I chose Empty Activity, so choose empty activity for this tutorial.

Activity-for-custom-font-project
Empty Activity for our TypeFace project

The default name is MainActivity, you don't need to make any change. If you wish to you can.

Custom Text Main Activity


After you've chosen the name and clicked on finish, you have created an empty Activity and you will see a screen similar to this. This is the MainActivity, extend AppCompatActivity for Support to lower versions if you want.

Custom-Text-App-Compat-Activity


Now create a new class. This class will contain the code related to our custom font textView

Custom-class-extending-textView


I've named the class NastyFontTextView :D. You might want to use a different name :P
 
Custom-class-extending-textView-for-custom-typface


Since we are creating a custom TextView class, we need to have all the properties of textView. So extend the regular TextView.

Custom-Class-extending-textView-for-custom typface


Since we want to set custom font using XML, we need to create an attribute using which we will define the typeface for a particular textView. So create a new attrs.xml inside you values folder. We will later use this attribute to define the font for the textView.

Creating-new-attribue-containing-font-property


Write the code shown in the screenshot below. This is doing nothing but just adding an attribute to the class MyTextView. We can use this attribute in XML to define custom font.

MyTextView-stylabe-for-custom-font-property


Now go back to our NastyFontTextView and use the default constructor. You can do it by pressing ALT+Enter.

Implementing-default-constructor-of-TextView

You will see a list of default constructor. Use the one with attributeSet.
attributeSet-constructor-for-extending-textView-class


Once you have selected the default constructor with attribute set, you will see that the following lines of code are added.

Default-constructor-in-custom-class-extending-textView


Now we need to get the font that the we have defined using the font property in XML and then we need to apply that font. We will use chooseFont and applyFont methods for that. Write the code seen below.
Note - You will see an Error in FontCache usage right now, as it's not a predefined class. We will create it in the next step.

Select-Typeface-and-apply-typeface-methods


Loading the font whenever you require them again and again in as inefficient process. So if you've loaded a specific font already one, we will cache it so that is can be used quickly the next time. Create custom class for fontCaching call it FontCache.

Creating-font-cache-class-for-easy-loading-of-custom-font


Font cache is a simple class. It just loads the fonts from fonts folder inside the assets and stores it in a hashMap. Here is the  complete code for FontCache Class.

FontCache-getTypeface-method


Finally, we are done on the Java part. You will notice that the FontCache error is gone!

Complete-class-for-apply-custom-font-in-all-activities


Now it's the simple part. We just need to use the custom class we created, NastyFontTextView in our layout. Open activity_main and add a NastyFontTextView. It works as plain old textView till now. Add app:font to it and let the magic begin! You define your own font in this attribute.
Note : Your font must exist in the fonts folder inside assets folder. 

Creating-layout-for-custom-font


You will see an error in app:font property, add xmlns:app name space to root layout and it will be gone. Press alt + enter and it will be added automatically. In the app:font property you can write any font name that you have copied in the fonts folder and it will be applied to that textView. Yesss!

adding-custom-font-class-to-layout


We will add a few more textView so that we can demonstrate all the TextViews with different Fonts. You don't need to do that but we will just because we can! :D
Change the root layout to linear layout as we won't have to define alignment for all the TextViews.

Changing-root-layout-for-custom-font


Add a new more NastyTextViews with fonts of your choice just as in the image below!

adding-class-extending-textview-for-custom-font


We have already done everything! we just need the TypeFace in the fonts folder. You can copy any typeface just Google and download if you haven't already decided on a sexy font yet! To create assets folder do this : right click on res->new->folder->Assets folder. Now go to assets folder and create fonts folder inside it and copy your fonts in it.

adding-custom-fonts-in-assets-folder


Here's the fonts that I've added inside my fonts folder.So we've learned how to create a custom class extending TextView that can be easily used in the XML and we can change font now with just one line of code! Bravo, go party unless you have any doubts, if you have drop them in the comments and I will try to answer it asap. Cheers!

custom-fonts-in-assets-folder-to-be-applied-in-all-activities

Source Code : Download Custom Font Tutorial

Wednesday

How to create a Location Tracker App in Android complete tutorial

Vishal Shrestha
Creating a basic but functional Location Tracker app in Android is not much work, you can do it within an hour! Just follow the following tutorial. Here we will create an Android App that will access GPS or Network to figure out your current location and keep updating the Marker on the map to give the effect of "Tracking". We will be using Google Maps Android API, Android Studio and an Android Phone to test.

If you are into videos : You can watch this YouTube Video :
Note - Find Source code of this location tracker app at the end of this article

Let's begin to create our very own Location Tracker App! Create a new project and Select the Google Maps Activity as shown in the figure below and just click next on the corresponding options and click on finish. Doing this gives us a template that already has a layout with maps fragment and an associated activity with the marker placed somewhere over Australia! We can run this app now by just adding our API_KEY.

Creating_location_tracker_app_android
Creating new MapsActivity Project


You will see a screen like this, at the second last line, notice YOUR_KEY_HERE. You need to get the API key for using google maps API for Android. You will need Google Maps to display your location on the map.

Google maps android API key
API_KEY


To get the API Key, go to this link - Google Maps Android API, and a webpage like the one below will open up. Now just click on the Maps link(The first option form the bottom image row). Update - Now you can click on GET A KEY button on top right, next to pricing and plans button.If you do this, skip the next step.

getting google maps android api key
Official Google Maps website



Now if you can see a page like this, click on the GET A KEY button right next to View Pricing and Plans button on the top right corner of the page.

Getting google maps android api key
Getting google maps API Key


Now you will be show a dialog box like the one shown below, here you need to give the project name for which you will be using Google Maps.

Google maps app android project name
Google Maps App Project Name


After you enter a valid project name, you will be shown a new dialog box with the you API KEY, Bravo. Now you can finally start coding you own Location Tracker app for Android. Copy the API_KEY shown to you in the dialog box, you will need it in the next step.

Google Maps Android API Key
Google Maps Android API Key


Now we are back in Android Studio, let's begin where we left off. Paste the API KEY that you copied from the dialog box in the previous step in the highlighted part shown in the screenshot below.
At this point we already have a functional app that puts the Marker over some place in Australia. The marker is static and you can change it to be placed over any place by defining the coordinates in the MapsActivity. You can run and test this app now, just add the following permissions in the Manifest :
 <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
 <uses-permission android:name="android.permission.INTERNET"/>

Android Studio Google Maps API Key
Android Studio Google Maps API Key



Now open your activity_maps.xml from the layouts folder inside res folder. It should look like the image shown below.

Google Maps Android Studio MapsActivity
MapsActivity


Now finally we can start some actual coding! Read, keep or remove the pre defined comments, I choose to remove it. Now create a new GoogleMap variable mMap and implement LocationListener. You need the LocationListener to be notified whenever your location changes. The implementation will show some error for now, it's because we haven't implemented the required methods yet.

LocatioinListener for getting location changes
Location Listener


To remove that error, implement all the required methods. Click ALT + Enter and you will be shown list of all the methods that can be implemented. Select all of them and click Enter. You will see the following methods and the error will have been resolved. Although there are a bunch of methods, we will only be using onLocationChanged which is called whenever new location data is received by the device. Here we handle what to do with the new data, put the marker over that point or do whatever you want with it.

Implementing LocationListener Methods
Implementing location listener methods


Now, create your own method called requestLocation. This method will be responsible for setting the criteria of the location requests that you will make. Criteria defines the accuracy level required and the power level required. According to your criteria the Android system automatically chooses GPS or Network for getting the your location so that you can focus on what you want rather that choosing the tool that you will be using.

Requesting location update from LocationManager
LocationManager and Criteria


Now you need to call the requestLocation method so the the device can try to figure out your location. But first you need to do some preparations, if you want your app to run on devices running Marshmallow or higher, you need to take care of Run Time permissions. To learn more about run time permissions, read this post - Marshmallow Runtime Permissions. You also need to add a new global Marker and MarkerOptions variable as you want to update the position of the same marker not create a new marker every time your position is changing. Initially we've set the marker position to 0,0. You'll see a lot of error for now as all the methods we've call are not yet defined. They are defined at the end of this tutorial. Write the code shown below in the screen shot.

Requesting location access permissions
Location Service Permissions


Since you have now called the requestLocation methods which requests your current location from the LocationManager, you can get you location data any second, so you need to handle your location data in the onLocationChanged method. Add the code shown below in onLocationChanged and add the marker to that place in the onMapReady.

Using onLocationChanged Method and using marker
Adding Marker on Map
Here's the code for the isLocationEnabled and isPermissionGranted method. isLocationEnabled checks if the location information can be given to apps i.e if apps are allowed to get the location information or not. isPermissionGranted method checks specifically for your app if your app is allowed to access location services or not. If not allowed it requests the permissions to the user.

Checking if location service is enabled
Checking if location service is enabled


Finally here's the code of showAlert. It shows a dialog box if the location services in your device is turned off, i.e if apps are not allowed to access you current location data. If the user choose to give the permissions then he/she is directly taken to the location setting options.

Showing alert for location service request
Showing Dialog Box

Finally our app is done! it wasn't that complex, was it? We have our own Location Tracker app which updates the marker in the map according to our position. The marker changes the position abruptly but the app tracks the location just fine. We can work on the smoothness of the change of marker's location some other time. Happy coding, if you have any problems, don't hesitate to comment below.

Source Code : Download Project Files

Android app crashes without any error or exception in logcat

Vishal Shrestha





The only thing worst than getting an error is getting an error and not knowing what error it is and where it is. This is not a common problem but every Android developer is susceptible to it. Your app might just crash without any error or without the common "Unfortunately the app has closed" message. In some cases the app is redirected to another activity after an activity has crashed. The errors are there, they are being output but they are not being displayed to you.
To fix this no error issue, you can try one of the following methods :

Android app crashes without any error or exception in logcat | Fixed:

1. Remove filters - This is the most common and simple mistake that developers make that hides the error logs from them. The logcat might have filters set that are not allowing the error logs to be shown, you can set it to only from your application or remove all the filters. I had once wasted a whole lot of my valuable time just because of this simple issue.

No-errors-show-in-logcat
No Filters in Logcat

2. Remove noHistory property of Activity in Manifest - This is not actually a crash. It's how the app is supposed to work if you have set the noHistory property in the Manifest to true. This property defines whether or not the activity should be removed from the activity back stack and finished when the user navigates to some other activity from it and it's no longer visible on screen.

3. Run in debug mode - You can try to run the app in debug mode. Android Studio has a debugger that enables you to debug the apps on the either the Emulator or any connected Android device. Here's how you can enable debugging mode in android studio, to start debugging, click Debug in the toolbar. Android Studio builds an APK, signs it with a debug key and installs it on your selected device. It is then run and the Debug window is opened for analysis.
Running app in debug mode for errors
Debug Mode
So I hope you can now finally see the details about your error in logcat and your app now crashes with error, developers have strange wishes sometimes :-P . Do let me know how it goes in the comment section below! Cheers!

Coprights @ 2017 | The Code City by Vishal Shrestha Vishal Shrestha