Posts

Using AndroidViewModel for accessing application context

If you want to use context in view model, you can't use ViewModel as  it does not provide you context needed for creating Database. So Android architecture components introduced AndroidViewModel. If we use ViewModelProvider(this).get(ProductListingVM::class. java ), it will cause error "java.lang.Class<com.example.swapnil.sat.models.ProductListingVM> has no zero argument constructor" thrown at runtime. So, how to use it? We shall pass AndroidViewModelFactory instance while creating the ViewModelProvider.  Let's have a look. MainActivity.kt import androidx.appcompat.app.AppCompatActivity import androidx.lifecycle.ViewModelProvider class MainActivity : AppCompatActivity() { lateinit var viewModel : ProductListingVM override fun onCreate(savedInstanceState: Bundle?) { super .onCreate(savedInstanceState) setContentView(R.layout. activity_main ) viewModel =ViewModelProvider( this , ViewModelProvider.Andro...

Sticky label using ConstraintLayout

Image
Purpose of this post is to create layout like If you notice, label "New" should move along with email title, i.e. if email title is wide it should move up to left of date, if title is small then should stick with title. While moving to end, title should ellipsize. It is shown below. Here is how we can achieve it. Constraint right of  tvTitle  to  tvTime  text view. It should have right margin of 64dp. How I have reached 64dp? "New" label fits properly inside width of 56dp. Add 4dp margin on both sides of new label, it comes to 64 dp. 56 (width)+ 4 (left margin) + 4 (right margin) = 64 dp Now add  tvNew  with left constraint to  tvTitle  and 4dp left margin. To make  tvTitle  to have small width when text is small (e.g. "Email Subject"), add  app :layout_constraintWidth_default= "wrap"  in the layout. Complete layout looks like this.

Configuring bitbucket pipeline for Android

Image
Bitbucket pipeline can be configured for an Android project using following steps. Step 1: Open "Pipelines" from left side of your repository page on bitbucket. Step 2: Select "Java (Gradle)" from "Choose a language template" on new page opened. Step 3: Select "commit" right bottom corner. Pic shown below: Previous step will add "bitbucket-pipelines.yml" in the repository. Step 4: Change file contents to Step 5: Replace license hash with hash stored in your android sdk's license folder. In my case license file is stored at /home/swapnil/Android/Sdk/licenses . Copy the hash stored in "android-sdk-license" file and paste it in place of "d56f5187479451eabf01fb78af6dfcb131a6481e". This step will ensure that, when pipeline downloads the sdk, its licenses will be automatically accepted and build will not fail. Apk can be downloaded from artefacts tab shown in pipeline.

Android bar chart using custom view

Image
Android lacks support for graph view. Here is my implementation of custom view showing bar chart. You can use this source file in your project. The view will appear like this. /* * Copyright (c) 2016, Swapnil Chaudhari. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * - Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A...

How to fix httpcomponents library in Android Studio

I had a project in eclipse which uses httpcomponents . The jars used in eclipse did not work in Android studio and I am using compileSdkVersion 23 with buildToolsVersion '23.0.2'. I have tried out several solutions and wasted 3 hours figuring out how import the httpcomponents libraries. To avoid wasting your time, here is how I fixed the issue: Changes in Module specific build.gradle i.e. /app/build.gradle Add following under android {...} useLibrary 'org.apache.http.legacy' packagingOptions { exclude 'META-INF/DEPENDENCIES' exclude 'META-INF/NOTICE' exclude 'META-INF/LICENSE' exclude 'META-INF/LICENSE.txt' exclude 'META-INF/NOTICE.txt' } Add following under dependencies {..} compile ('org.apache.httpcomponents:httpmime:4.3'){ exclude group: 'org.apache.httpcomponents', module: 'httpclient' } compile ('org.apache.httpcomponents:httpcore:4.4.1'){ exclude group: 'org.apache.htt...

Configuring Gradle

Image
Android studio uses new build system called Gradle. We can use it to build project and configure server urls, settings or replace assets. 1. Following example shows build.gradle file to change server url depending upon the build flavor. I am using two flavors 1. devel 2. prod. For simplicity I shall keep it simple without configuring it for signing. Both flavors define a config variable "HOST" with different value to be used, when apk is built. If developer chooses, to have "devel" build, it will come with "http://192.168.1.34:3000" as HOST. productFlavors { devel { buildConfigField 'String', 'HOST', '"http://192.168.1.34:3000"' } prod { buildConfigField 'String', 'HOST', '"http://api.zuul.com"' } } To access the config constant use following code. String string = BuildConfig.HOST; 2. Following example shows how t...

Restoring activity state after changing configuration

Following are the techniques to save data so that activity can resume from where it had destroyed. 1. onSaveInstanceState() You can save your serializable data in a bundle and android will save this bundle for you. The same bundle will be returned to you on on in onCreate() and onRestoreInstanceState() callback methods. onRestoreInstanceState() is called after onStart(), whereas onCreate() is called before onStart(). These methods are only called when needed, that is when an activity has been destroyed (because of lack of resources) and needs to be recreated by the system. Because the onCreate() method is called whether the system is creating a new instance of your activity or recreating a previous one, you must check whether the state Bundle is null before you attempt to read it. If it is null, then the system is creating a new instance of the activity, instead of restoring a previous one that was destroyed. e.g. @Override protected void onCreate(Bundle savedInstanceState) { ...