Monday, July 10, 2017

Gitlab Shared Runner CI with Docker Tutorial - Complete Guide on Building Android Studio Project in Gitlab

After a long break, writing a new post on building Android Studio Gradle project on Gitlab Pipelines with Docker without hassling about server charges or build time. Gitlab Pipelines and Registry is a boon for developers who need CI for their apps and additionally, Gitlab provides private repo. Today let's look at creating a pipeline with an environment where our app is built within Docker when you commit to Gitlab repository.


Gitlab Shared Runner CI with Docker Tutorial - Build Android Studio Project in Gitlab

One of the most hassling things is building the project and moving into production phase by testing the app on several devices. The thing is maintaining a private server to build your production ready apps will cost you high like Travis CI, Circle CI. For startup companies, Gitlab shared runner is more than enough for building the application and delivering it with artifacts on regular basis.


Getting Started:

If you're familiar with Docker basics, It would be fine to continue with this tutorial. If not you can just learn about Docker basics here. Docker is an awesome environment where you virtualize your environment from the Host environment and run your specific test, build, commands. Since you virtualize your docker environment you won't be affected by external dependencies or prone to vulnerabilities while shipping your application. If you don't have Gitlab Account, signup now. It's completely free for individual developers.
  1. Create Gitlab Repo 
  2. Commit your Android Studio project in master branch

Enabling Shared Runner and Pipeline in Gitlab:

After creating the project, visit Settings -> Pipelines in your project repo and make sure Shared Runner is Enabled. You may get up to 4 Shared instance to build your project. Fortunately, Gitlab has collaborated with DigitialOcean to maintain servers for running such builds, test for users. so, you need not worry about scaling, downsizing the server size. 

Gitlab Shared Runner CI with Docker Tutorial - Complete Guide on Building Android Studio Project in Gitlab
Enable Shared Runner for this Project

Build Configuration File

In order to trigger our build, we need to write some configuration file. First, let's build our Docker image using Dockerfile. Gitlab too provides private docker registry for users, where you can build the Docker image in the pipeline and upload it to Gitlab registry. So, this will reduce our build time in halfway because installing our build tools ( Android SDK ) and other tools earlier will reduce the time and concentrate on compiling the source code into APKs.

Our Docker file looks like given below, it's just series of Linux commands where you process it and save it as Docker image. Whenever need you can deploy it as a container and make your desired process run inside the Docker container.

Prerequisites :

  • Create a new branch from existing master branch, remove all your application code. 
  • Create new file named as Dockerfile
  • Checkout docker file snippet below
  • Create new file named .gitlab-ci.yml 
  • Checkout Gitlab-ci file below, customize it as per your repository name
  • Commit all your files, this will automatically trigger a build to create new Docker Image and upload it to Docker registry.
Dockerfile for creating Android environment image is given below,




gitlab-ci.yml file for instructing the pipeline to perform the job is also given below, kindly replace with your own repository registry name, branch name or else build won't be triggered.


once you commit your code, Gitlab automatically triggers an Image Build in the pipeline. if everything goes smooth, your docker image will be uploaded to your Gitlab Docker registry. You can use the Docker image for further building the project without any hassle. Whenever you need to refresh or update your SDK tools, you can simply change and commit it, that will trigger an image building process and it'll be uploaded to your Gitlab Docker registry.

Gitlab Shared Runner CI with Docker Tutorial - Complete Guide on Building Android Studio Project in Gitlab
Building process after each commit

Build your Application:

Switch to your master branch, start writing similar gitlab-ci.yml file to instruct the build machine in order to trigger build and building the artifacts. It's going to be normal Gradle commands to build your application project and generate your APKs, AAR files and even more out of it. you can sign your application here with confidence by adding your Keystore file as Environment variable.

Let's look at our configuration file for building the application,



So, in before script, we added execution permission for gradlew executable file in user level (normally root/guest in terms of Docker). In build script, we simply added our Gradle command to build our application project. Since it's a sample I haven't added release build script here. After building process is over, you can specify your artifact folder, so that Gitlab can detect that folder and make it available for downloading. Normally it contains your project APK files, logs, Gradle profile report and even more if you have used custom tasks in Gradle.

So, commit this code and Gitlab will automatically trigger a build. Now, Docker is launched in a shared runner and then your Gradle scripts will be running to produce APK. It's up to you to have some integration with Gitlab to deliver your APK artifacts into team e-mails, slack channel, chat or even more.

Gitlab Shared Runner CI with Docker Tutorial - Complete Guide on Building Android Studio Project in Gitlab
Application building in Docker Container

Skip triggering build for each commit

you can skip the triggering build by adding an extra commit message, such as [skip ci] or [ci skip]. This will be automatically understood by Gitlab and it won't be triggering build automatically.

I hope this was an awesome tool for Developers who don't need to write the script for building, launch Build server and run, test, build your source code into release files. You don't need to worry about infrastructure, deliver and testing it seamlessly.


Gitlab Shared Runner CI with Docker Tutorial - Complete Guide on Building Android Studio Project in Gitlab
pipeline containing previous Docker Image Build and Artifact build


If you've any doubts, comment below or chat with me in Google+/Fb. Share is care.

Tuesday, May 16, 2017

Google launches new Tools to help the developers for producing high performance Daydream Apps

Daydream Apps will be striking feature in the Android Nougat release. Building this VR experience is mission critical task for all the developers involved. Because it’s like explaining the entire game of thrones story in an hour. There are lots of possibilities and corner cases.
Building this VR apps process must be scalable, that is the apps developed must not consume the entire resource or the device must not get overheated.
Google launches new Tools to help the developers for producing high performance Daydream Apps

So to help the developers who are working on this Google has announced brand new tools for producing high performance Daydream apps. So to begin with, let's have a look on Daydream Renderer.

Rendering is an important aspect when it comes for
developing VR apps. Because Rendering is the thing which makes the user to feel the impact. To produce the impact of rendering the secret is the art of producing light and shadows in the visuals at appropriate places. As per Google, this Daydream Renderer is a set of optimized tools that allows the user to produce dynamic lighting and shadowing in the visuals that gives an authentic impact to the users.


 
Developers who are constructing the games for the daydream platforms will be getting more benefitted from this Daydream Renderer. As the lighting and shadowing is very essential for making the user to stay intact with the game. This Tool will do that for sure as per the Google. Speaking about the VR for Games, Actually Roulette in Casino is my favourite Game, I used to play online roulette at casino.com. Roulette is an game in casino that actually stimulates one's brain to choose the exact option among the various possibilities.

Then moving on to next, Instant Preview

Normally a Developer writing a mobile application follows the process of writing a code, then compile and upload the change to a mobile device and test whether the change works for it. So at the end of the day a developer will spend several minutes idle during the entire process.  

But the Instant Preview now introduced by Google ensures that this process could be completed in seconds therefore saving the time of a developer increasing the productivity. It also ensures Quality allowing developers to do more iterations in less time.


Google has also introduced performance monitoring tools like GAPID and PerfHUD
 
Though the VR Apps looks just great, it will reach wide range of users only when it performs in an optimized way. The device on which the VR apps runs must not get overheated and the VR apps must run with no dependence upon the device or the environmental condition.

gapid permits the developers to perform deep GPU profiling providing ideas upon how the hardware and software interacts to drives performance. It also allows the developer to search for any other corner case that could bring the entire performance down.

PerfHUD is an another extraordinary tool which helps the developers to rightly plot which areas of the games and apps push the hardware of the device too hard.

So, looking through the future VR is going to be next big game changer for Game Industry and enables the user to use virtual reality from their smart phone devices.

How to build an iOS App with the Xcode 8 and Swift 3

Hello developers, In this tutorial I'm gonna show you how to build an iOS App with Xcode.


What is Xcode and Swift ?

     Xcode is a integrated development environment which is developed by apple for developing iOS, macOS, watchOS and tvOS Apps. It comes with iOS SDK, compilers, debugging tools and simulators etc. Install the Xcode app from the Mac App Store itself or download it from here. Note: To install Xcode, you need to have Mac machine.

     Swift is a new programming language developed by Apple Inc and it's release by Chris Lattner in 2010. Swift comes with Playground to write swift program and the outputs are displayed in right pane. It shows the results very fast and you no need to click any run buttons to execute the program. It is very interesting know ? Swift has a lot of features and it has a huge libraries too. The extension of swift program is .swift 

     Okay now let's create our new project and start to build our first iOS App in Xcode.

Creating a Project

  • Open Xcode and Create a new project from the file menu.
  • Select Single View Application template and click Next.
  • Give name to product, organization and organization identifier. See below image for reference.

Adding Views 

  • Click the Main.Storyboard file.
  • Drag and drop the Label and Button from the Object Library into the View. Do like below image.


  • Now open the Assistant Editor in Xcode. Click the double circled icon in top right corner(See the image below) or Click CMD + OPTION + ENTER shortcut.


  • Then drag and drop the label and button into the view controller(viewcontroller.swift file)





  • Then it'll show you one tiny window, in that you've to change the connections and click connect. For button, change the connection from Outlet into Action. For Label, set the connection as Outlets(By default, it's Outlet only) 





View Controller Code

import UIKit

class ViewController: UIViewController {

    @IBOutlet var helloWorldLabel: UILabel!
    
   
    @IBAction func clickMeBtnPressed(_ sender: Any) {
        
        //Setting hello world label into Welcome to iOS World
        helloWorldLabel.text = "Welcome to iOS World"
        
        
    }
    
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        
        print("viewDidLoad function is called")
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


}

Run the App

      Now build the project and run it. Then the app will open in Simulator.




Boom!!! Just click the "Click Me" button then the label will changed from "Hello World" to "Welcome to iOS World". We've completed our first hello world iOS app in Xcode using Swift 3. I hope you guys understand and if you've any doubts in this tutorial then just drop your comments. See you in the next tutorial...

Friday, April 28, 2017

Working with Pdf JS - Render PDF natively in Browser Tutorial

Posting Web tutorial after a long time with a lot of energy and possibilities. There would be few things in life which would be life changing and support you even in worst times, yes of course, my blog and readers are my supporters who support me throughout my journey. 

Working with Pdf JS - Render PDF natively in Browser Tutorial - i-visionblog


Download 

Why Pdf.js? 

Pdf Js is awesome javascript library supported by Mozilla and Individual contributors to make the web a beautiful place to visit and get work done. So, Every browser is capable of viewing Pdf files and what is so special about the pdf.js library is you can control the pdf with Javascript code rendering, switching pages and even more. So, Developer has the ultimate power to control the pdf loaded from the server and rendering part in the client. PDF are awesome documents that are daily shared between business for invoices and business payment processing documents, official agreements, documentations even more possibilities.

Use cases:

When you're building an application that heavily depends on the pdf view to the customer and need to render as a part of the application, pdf js is right choice to go with it. Where you can control the contents of the pdfs with session maintenance (premium and free customers ), personalized pdf rendering.

Getting Started:

Integrating pdf.js into your web/mobile web application is straightway easy but requires knowledge about javascript promises. To write clean and remove callback-style code, Promises are introduced.

Integration:

Either you can use pre-build version or you can clone the source code from GitHub and try to build with gulp command. I prefer to build the Javascript library from source. If you want to use it directly you can refer pastebin reference code.

building process commands:
Make sure you have node.js installed in your system with sudo access. Open the shell and try to execute the commands. First of all clone the GitHub repo.
 > cd <Pdf.js repo>
 > npm install  
 > gulp generic 

By running above commands, you can successfully build the source code into distribution code (dist) in the build directory. You can use this as javascript library importing it as a script.

Importing:

You can simply include the pdf.js in your script tag along with the pdf.worker.js file. Once it has been setup you need to write application logic based on your web application.


<head>

<title>Pdf.js Example Application | i-visionblog</title>
<script src="build/pdf.js"></script>
<script src="build/pdf.worker.js"></script>
<script src="js/app.js"></script>
</head>

So, this will import the whole pdf.js and its recommended to go for minified version while moving into production mode.

PDF.js API to render pdf:

pdf.js uses Ajax feature to load the pdf from the server. It reduces the memory footprint by loading the pdf by pagewise instead of loading all at a time. In fact, that's bad practice to load all pdf content at a time unless it is too important. PDF.js also uses a separate worker to download and render the content to Html DOM (document object model). We could getPage(index) method to load the page and use render() function to render the page in the Html DOM. It also uses Context to instruct the height, width, scale and element container to load. But it all works with promises to reduce the callback-style of coding. Here is sample javascript snippet to load all the pages into the canvas.



Final Words:

You can download the whole application project from here. The above code simply loads the pdf from the local server and then renders all pages into Html DOM as canvas images. It's up to you to devise your own event click listeners to load next and previous pages as per your application logic.

Hope you've liked this article. Subscribe for more tutorials and follow me in Google+/Facebook for updates. If you have any doubts chat with me or drop me a mail. Feel free to comment below. Share is care.

Tuesday, April 25, 2017

How to Make an Explainer Video

Creating an explainer video is a great way to attract the attention of prospective customers. By giving people solutions to common problems, you build trust — which often translates to custom over time. Your company may be able to solve the problems or provide the solutions they need, but in order to get this message across, you need to explain exactly what your business is about. This is where best explainer video comes in.
Consumers are bombarded with information, and they have relatively short attention spans as a result. To explain what your company does using text might take 600 words or more, which would take up 10 minutes of a person’s precious time. But by creating a video, you can deliver the same information quickly and in a more engaging way.
In order to create the best explainer video you can, there are several steps you need to take.

Write a compelling script

The video making process should start with a script. Your video should follow a logical, linear narrative, and it should contain all of the essential information you need to communicate in a way that will be engaging and informative. By writing a script, you can be sure that you’re creating the best explainer video possible from the very beginning of the process.

Create a storyboard

Once you have a completed script, you can use it to start putting the visual aspects of your video in place — with a storyboard. Think of your storyboard as a visual sketch of what your video is going to look like. This gives you a tactile method of experimenting with different scenes and visuals before you start the video production process. Try out different movements, transitions and angles on your storyboard until you’re happy that what you’ve created will deliver the right message.

Enlist the services of a narrator or voice-over

The narrator or voice-over tells the story to complement the visuals in your video. This is where your script comes to life, so it’s important that you choose someone with an engaging and clear voice. It’s definitely worth spending some money on hiring a professional voice-over, as the right voice will make your audience feel more engaged with the story — and your company.

Animate your video

This is probably the most important task you will need to complete during the entire process. As videos on most social media platforms play on mute until they are clicked, your visuals need to be professional, visually engaging and interesting. You need to capture the attention of prospective customers within a few seconds, so what they see on the screen has to be impressive. Don’t cut corners here: hire a professional animator to create visuals that will stun your audience. A talented animator will take your script and transform it into a visual story that flows seamlessly. Music, sound effects and text will also add to the overall aesthetic — creating a video that will represent your brand in the best possible way.

Publish and track the results

Publish your video on your own website, relevant third-party websites and on all of the main social media platforms. It’s vital that you track how your video is performing — both in terms of click-through rates, conversion rates and the general feedback of your audience. Depending on the results, you might want to tweak your video slightly. Consider implementing A/B testing on two different videos in order to see which approach delivers the best results.

If you can create an informative and engaging explainer video, you should be able to use it for driving high quality traffic to your website. This not only grows your business, it builds your brand.

Hope you've liked this post, if any doubts feel free to comment below or chat with me in Google+/ Facebook. Share is care.

Saturday, March 11, 2017

Android TabLayout Tutorial - Material Design Support Library

TabLayout is excellent user experience design component to arrange heterogeneous data in similar fashion aka categorization. Even Google Play store categorize Apps, Games, Magazines apps under tabs. Drilling down in depth Apps are categorized as Top Paid Apps, Free Apps, Trending Apps and even more as Sliding Tabs. Tabs became famous when they were introduced in Google I/O iosched application where it was implemented using SlidingTabLayout with help of viewpager component, co-ordinating the both working TabLayout was born and brought to Support library as plug and play UI component.




Download:

You can check out the source code from github repo.

Use case:

  1. When you are able categorize different types of tag containing huge amount of similar data
  2. Manage different options as tabs under single activity

Prerequisites:

  1. Android Studio with Appropriate SDK installed - Installation Steps for Ubuntu 16.04
  2. Android Support Repository installed via SDK manager
  3. Create New Android Studio project

Getting Started:

compile 'com.android.support:appcompat-v7:25.2.0'
compile 'com.android.support:design:25.2.0'
compile 'com.android.support:support-v4:25.2.0'    

Add these dependencies to buid.gradle file and hit the gradle sync button. Once you've synced these libraries and methods are available for you in offline.

Adding XML layout:

Setting up Tablyout for your application is pretty simple and straight forward. open your main activity.xml file and start typing the sample code given below.


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.ivisionblog.apps.materialtabsexample.MainActivity">

    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:layout_scrollFlags="scroll|enterAlways"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />

        <android.support.design.widget.TabLayout
            android:id="@+id/tabs"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:tabMode="fixed"
            app:tabIndicatorColor="@color/colorAccent"
            app:tabGravity="fill"/>
    </android.support.design.widget.AppBarLayout>

    <android.support.v4.view.ViewPager
        android:id="@+id/viewpager"
        android:layout_width="match_parent"
        android:layout_height="0px"
        android:layout_weight="1"
        android:background="@android:color/white" />
</LinearLayout>
Here AppBarLayout contains Toolbar and TabLayout which co-ordinates the scrolling behavior, and then Viewpager to help to manage different fragments corresponding to the tabs by managing memory efficiently.

Bind Fragments to Tabs:

After creating XML design layout, we need to bind layout to corresponding Fragments with Tabs using Adapter. So, we need to create TabAdapter to hold all our fragments which is used by viewpager to manage those fragments and its corresponding memory.

public class MainActivity extends AppCompatActivity {

    private TabLayout tabLayout;
    private ViewPager viewPager;

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

        Toolbar mtoolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(mtoolbar);
        getSupportActionBar().setTitle("Customer App");

        viewPager = (ViewPager) findViewById(R.id.viewpager);
        addFragmentsToViewPager(viewPager);

        tabLayout = (TabLayout) findViewById(R.id.tabs);
        tabLayout.setupWithViewPager(viewPager);

    }
    private void addFragmentsToViewPager(ViewPager viewPager) {
        TabAdapter adapter = new TabAdapter(getSupportFragmentManager());
        adapter.addFragment(new CustomersFragment(), "Customers");
        adapter.addFragment(new ContactsFragment(), "Contacts");
        viewPager.setAdapter(adapter);
    }

}

TabAdapter.java:

class TabAdapter extends FragmentPagerAdapter {
    private final List<Fragment> mFragmentList = new ArrayList<>();
    private final List<String> mFragmentTitleList = new ArrayList<>();

    public TabAdapter(FragmentManager manager) {
        super(manager);
    }

    @Override
    public Fragment getItem(int position) {
        return mFragmentList.get(position);
    }

    @Override
    public int getCount() {
        return mFragmentList.size();
    }

    public void addFragment(Fragment fragment, String title) {
        mFragmentList.add(fragment);
        mFragmentTitleList.add(title);
    }

    @Override
    public CharSequence getPageTitle(int position) {
        return mFragmentTitleList.get(position);
    }
}
Thus above code maintains fragment and title as List which is extended from FragmentPagerAdapter and override the getItem and getCount method to implement. Whenever Viewpager(While swipeing or changing the tabs) requires the Fragment it calls the getItem method and which returns the Fragment to inflate into the view.

Sample Fragment:

I've added sample Fragment containing Recyclerview which is populated with Contacts data with Contacts Adapter and bind the data into the Recyclerview single contact view. The most important thing is it's good to write the recyclerview implementation in onActivityCreated method inside the fragment.


public class ContactsFragment extends Fragment {

    private RecyclerView mRecyclerview;

    public ContactsFragment() {
        // Required empty public constructor
    }

    public static ContactsFragment newInstance() {
        ContactsFragment fragment = new ContactsFragment();
        Bundle args = new Bundle();
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_contacts, container, false);
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        mRecyclerview = (RecyclerView) getActivity().findViewById(R.id.contactlist);

        ContactsAdapter contactsAdapter = new ContactsAdapter(generateData());
        RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getContext());
        mRecyclerview.setLayoutManager(layoutManager);
        mRecyclerview.setAdapter(contactsAdapter);
    }

    private ArrayList<ContactsModal> generateData(){
        ArrayList<ContactsModal> contactsModals = new ArrayList<>();

        contactsModals.add(new ContactsModal("Midhun Vignesh S","987654321"));
        contactsModals.add(new ContactsModal("Shivasurya S","987654321"));
        contactsModals.add(new ContactsModal("Aswin Vayiravan","987654321"));
        contactsModals.add(new ContactsModal("Muthu Alagappan M","987654321"));
        contactsModals.add(new ContactsModal("SriramaMoorthy S","987654321"));
        contactsModals.add(new ContactsModal("Puviyarasu V","987654321"));
        contactsModals.add(new ContactsModal("Arun Kumar K R","987654321"));
        contactsModals.add(new ContactsModal("Venkat Raman","987654321"));

        return contactsModals;
    }
}
    

Sample RecyclerView Adapter & Holder:

Check out the sample recyclerview adapter and holder class to support our recyclerview which is embedded in our fragment xml file.

public class ContactsAdapter extends RecyclerView.Adapter<ContactsAdapter.ContactsHolder> {

    private ArrayList<ContactsModal> mContactsModals;
    private FragmentManager mFm;

    public ContactsAdapter(ArrayList<ContactsModal> contactsModals){
        mContactsModals = contactsModals;
    }

    @Override
    public ContactsHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        Context context = parent.getContext();
        LayoutInflater inflater = LayoutInflater.from(context);

        View contactView = inflater.inflate(R.layout.single_contact, parent, false);

        ContactsHolder viewHolder = new ContactsHolder(contactView);
        return viewHolder;
    }

    @Override
    public void onBindViewHolder(ContactsHolder holder, int position) {
        ContactsModal contact = mContactsModals.get(position);

        holder.mPhoneView.setText(contact.getmPhoneNumber());
        holder.mContactsNameView.setText(contact.getmName());
    }

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


    public static class ContactsHolder extends RecyclerView.ViewHolder{

        TextView mContactsNameView;
        TextView mPhoneView;

        public ContactsHolder(View itemView) {
            super(itemView);
            mContactsNameView = (TextView) itemView.findViewById(R.id.nameView);
            mPhoneView = (TextView) itemView.findViewById(R.id.phoneNumberView);
        }

    }
}

And finally Fragment and single contact xml file code goes below,

<FrameLayout 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"
    tools:context="com.ivisionblog.apps.materialtabsexample.fragments.ContactsFragment">
    <android.support.v7.widget.RecyclerView
        android:layout_width="match_parent"
        android:id="@+id/contactlist"
        android:layout_height="match_parent">

    </android.support.v7.widget.RecyclerView>
</FrameLayout>
Single Contact XMl file which used by contacts adapter to inflate inside recyclerview,

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:clickable="true"
    android:focusable="true"
    android:foreground="?android:attr/selectableItemBackground"
    android:background="?android:attr/selectableItemBackground"
    android:layout_height="wrap_content">
    <LinearLayout
        android:layout_width="match_parent"
        android:orientation="horizontal"
        android:layout_height="wrap_content">
        <LinearLayout
            android:layout_width="0dp"
            android:layout_weight="2"
            android:layout_gravity="center"
            android:layout_height="wrap_content">
            <ImageView
                android:layout_width="match_parent"
                android:src="@mipmap/ic_launcher_round"
                android:layout_height="wrap_content" />
        </LinearLayout>
        <LinearLayout
            android:layout_width="0dp"
            android:layout_weight="8"
            android:orientation="vertical"
            android:layout_height="wrap_content">
            <TextView
                android:layout_width="match_parent"
                android:text="Shivasurya S"
                android:textSize="18sp"
                android:layout_marginTop="15dp"
                android:layout_marginLeft="15dp"
                android:textStyle="bold"
                android:id="@+id/nameView"
                android:layout_height="wrap_content" />
            <TextView
                android:layout_width="match_parent"
                android:text="9788029400"
                android:textSize="15sp"
                android:layout_marginTop="10dp"
                android:layout_marginLeft="15dp"
                android:id="@+id/phoneNumberView"
                android:layout_height="wrap_content" />
        </LinearLayout>
    </LinearLayout>
    <View
        android:layout_width="match_parent"
        android:background="#e7e7e7"
        android:layout_marginTop="5dp"
        android:layout_height="3dp"/>
</LinearLayout>
Thus, We have successfully integrated Tabs with Recyclerview inside fragments in our application. If you want customization of tabs in your application you can check the table and attribute into your TabLayout xml code as app:attribute namespace

The most important properties available are listed below:
NameOptionsDescription
tabBackground@drawable/imageBackground applied to the tabs
tabGravitycenterfillGravity of the tabs
tabIndicatorColor@color/blueColor of the tab indicator line
tabIndicatorHeight@dimen/tabhHeight of the tab indicator line
tabMaxWidth@dimen/tabmaxwMaximum width of the tab
tabModefixedscrollableSmall number of fixed tabs or scrolling list
tabTextColor@color/blueColor of the text on the tab

Hope you have enjoyed this post, checkout official Google Android documentation for further updates in forcoming support library versions. Feel free to comment below for doubts or chat with me in Google+/Facebook or drop me e-mail for replies. Share is care.

Friday, March 10, 2017

Android Bottom Sheet Example - Android Support Library Tutorial

Bottom Sheets is excellent user experience design component when comparing long press dialog pop-up box, context menu where the user can consume options easily from the bottom with attractive and meaningful user interface. So, let us dive into the implementation of Bottom Sheets in the Android application using official android support library.


Android Bottom Sheet Example - Android Support Library Tutorial

Prerequisites:

  1. Android Studio and SDK installed - How to install android studio
  2. Bottom Navigation Drawer Tutorial - If you're interested check out this article

Getting Started:

Add support library dependency in build.gradle file and sync it via android studio

compile 'com.android.support:design:25.2.0'
compile 'com.android.support:support-v4:25.2.0'    
Use gradle sync to download all the support libraries and import to your project.

Adding Layout: 

In order to add Bottom sheets to the activity, NestedScrollView is used with additionally bottom sheet behaviour with other options. check out the layout xml file below.

<?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="com.ivisionblog.apps.bottomsheetexample.MainActivity">

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

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

    <android.support.v4.widget.NestedScrollView
        android:id="@+id/bottom_sheet"
        android:layout_width="match_parent"
        android:layout_height="350dp"
        android:clipToPadding="true"
        app:behavior_hideable="true"
        android:elevation="14dp"
        android:background="@android:color/holo_blue_light"
        app:layout_behavior="android.support.design.widget.BottomSheetBehavior">


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

Bottom Sheet behavior is adopted for the nested scroll view with attribute named as app:layout_behavior which implements the bottom sheet behavior.

Java Implementation:

We'll try to add Bottom Sheet dialog box behavior in this tutorial, simply extend your fragment class with BottomSheetDialogFragment and start implementing the onCreateView method for building the fragment user interface, check the code below for understanding.



public class BottomDialogFragment extends BottomSheetDialogFragment {
    public static BottomDialogFragment getInstance() {
        return new BottomDialogFragment();
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view =  inflater.inflate(R.layout.bottom_sheet_fragment, container, false);
        ((TextView)view.findViewById(R.id.name)).setText("Elon Musk");
        return view;
    }
}

Thus this will help in creating fragment and inflating into the bottom sheet view, now let us see how to control the bottom sheet from our activity by responding to user clicks. Since i've used Recyclerview added click event and binding the bottom sheet behavior with recyclerview click event.


public class MainActivity extends AppCompatActivity {

    private RecyclerView mRecyclerView;
    private BottomSheetBehavior mBottomSheetBehavior;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mRecyclerView = (RecyclerView) findViewById(R.id.recyclerview);
        mRecyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));

        View bottomSheet = findViewById( R.id.bottom_sheet );
        mBottomSheetBehavior = BottomSheetBehavior.from(bottomSheet);
        mBottomSheetBehavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
            @Override
            public void onStateChanged(View bottomSheet, int newState) {
                if (newState == BottomSheetBehavior.STATE_COLLAPSED) {
                    mBottomSheetBehavior.setPeekHeight(0);
                }
            }

            @Override
            public void onSlide(View bottomSheet, float slideOffset) {

            }
        });
        ContactsAdapter contactsAdapter = new ContactsAdapter(generateData(),mBottomSheetBehavior,getSupportFragmentManager());
        mRecyclerView.setAdapter(contactsAdapter);
        mBottomSheetBehavior.setState(BottomSheetBehavior.STATE_HIDDEN);

    }
}

Bottom Sheet behavior based on Recyclerview click Event:

Now let us map recyclerview click event with bottom sheet behavior event, so that whenever it is clicked bottom sheet opens up with transition from down. check the Recyclerview adapter code for detailed understanding.


 @Override
    public void onBindViewHolder(ContactsHolder holder, int position) {
        ContactsModal contact = mContactsModals.get(position);

        holder.mPhoneView.setText(contact.getmPhoneNumber());
        holder.mContactsNameView.setText(contact.getmName());
        holder.mLinearLayout.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                BottomDialogFragment bottomSheetDialog = BottomDialogFragment.getInstance().getInstance();
                bottomSheetDialog.show(mFm, "Custom Bottom Sheet");
            }
        });
    }

Bottom Sheet Useful Methods:

  1.  BottomSheetDialog.show() - To open the Bottom sheet dialog from hidden state to expanded state
  2.  BottomSheetBehavior.setState() - To set the state of the bottom sheet behavior from java code based on events.
  3. BottomSheetBehavior.setPeekHeight(int) - To set the Peek Height of the bottom sheet from the bottom.  
For full working sample, follow the Github repo. Just clone and open in android studio to execute the bottom navigation drawer view android example application. This Bottom Sheet view is bundled with Android support library officially and it's worth trying out in your application.

Hope you have enjoyed the post, post you own thoughts, additional points as comments. For complete code, projects, hugs/bugs just drop me mail/ chat in Facebook/Google+. share is care.