Android prevent parent from intercepting touch events

I was developing a custom component like a slider, where a user can drag the thumb on the slider horizontally. But i was facing a problem while dragging the thumb, after dragging a few pixels the thumb would get released.

I checked and debugged the code and then i got to know that i was getting MotionEvent.ACTION_CANCEL in onTouchEvent function.

The real problem was my custom component (slider) was placed inside a ViewPager, and ViewPager was preventing the dispatch of the touch event to the child(slider). When we drag finger over the ViewPager, it tries to swipe the page and shows the next page, due to this property of the ViewPager, onInterceptTouchEvent of the ViewPager was returning true and from that point ViewPager will consume all the dragging touch event.

Solution

Solution of this problem is to use the requestDisallowInterceptTouchEvent of the ViewGroup class, when we call this method on the parent and pass it true, from that moment the parent will not intercept the touch events and will pass all the touch events to the child’s.

Following is modified onTouchEvent method

public boolean onTouchEvent(MotionEvent event) {
     if(!isEnabled()) {
         return true;
     }
     float y = event.getY();
     float x = event.getX();
     final int action = event.getActionMasked();
     switch (action) {
         case MotionEvent.ACTION_DOWN:
             //request the parent not to intercept event
             getParent().requestDisallowInterceptTouchEvent(true);
             //do your stuff 
             break;

         case MotionEvent.ACTION_MOVE:
             //do your stuff
             break;
         case MotionEvent.ACTION_UP:
             //we are done sliding, parent can intercept the touc event if required
             getParent().requestDisallowInterceptTouchEvent(true);
             //do your stuff
             break;
         case MotionEvent.ACTION_CANCEL:
             //we are done sliding, parent can intercept the touc event if required
             getParent().requestDisallowInterceptTouchEvent(true);
             //do your stuff
             break;
     }
     return true;
 }

I hope this will help other developers.

Thanks !!!!

Posted in advanced

Android N requires JDK 1.8 or later to compile

Hi developers,

Recently i updated the Android sdk to api level 24 that is Android N (Nougat) and got the following error

Error:Execution failed for task ‘:app:compileDebugJavaWithJavac’.
> compileSdkVersion ‘android-24’ requires JDK 1.8 or later to compile.

How to fix this error?

  •  1. Download and install JDK to 1.8 or letter.
  •  2. In Android studio go to File->Project Structure
  •  3. Change the JDK location to newly installed JDK .

project_structure

Recompile the project and this should fix the error.

Thanks.

Posted in Uncategorized

Android Plurals (Quantity Strings)

Android has a nice feature called Quantity Strings (Plurals) to get the appropriate string based on the quantity.

Suppose the application shows the nearby restaurants to the user by calling a web service and shows the result like

“2 restaurants found, would you like to check them?”

and we keep the above string in strings.xml

<resources>
    <string name="restaurant_result">%d restaurants found, would you like to check them?</string>
</resources>

The result might be different depending upon the location, so suppose only one restaurant found then we can not use the same string because it is grammatically incorrect. Instead we need to add one more string to handle this and the new string.xml is as below

<resources>
    <string name="restaurant_result_single">%d restaurant found, would you like to check it?</string>
    <string name="restaurant_result_multiple">%d restaurants found, would you like to check them?</string>
</resources>

But here is one problem, we need to add some conditional logic to get the appropriate string based on the restaurant count, something like below function.

int restaurantCount = getNumberOfRestaurants();
Resources resources = getResources();
String result;
if(restaurantCount == 1) {
    result = resources.getString(R.string.restaurant_result_single, restaurantCount);
} else {
    result = resources.getString(R.string.restaurant_result_multiple, restaurantCount);
}

Here comes plurals in the picture, to use plural feature we  need to modify the strings.xml like below

<resources>
    <plurals name="restaurant_result">
        <item quantity="one">%d restaurant found, would you like to check it?</item>
        <item quantity="other">%d restaurants found, would you like to check them?</item>
    </plurals>
</resources>

So to get the appropriate string based on the restaurant count we need to use getQuantityString method, the modified code is as below.

 int restaurantCount = getNumberOfRestaurants(); 
Resources resources = getResources(); 
String result = resources.getQuantityString(R.plurals.restaurant_result, restaurantCount, restaurantCount); 

Note that When using the getQuantityString() method, you need to pass the count twice if your string includes string formatting with a number.
For example, for the string "%d restaurant found, would you like to check it?", the first restaurantCount parameter selects the appropriate plural string and the second restaurantCount parameter is inserted into the %d placeholder.
If your plural strings do not include string formatting, you don’t need to pass the third parameter to getQuantityString.

Following are the possible plural quantities

  1. zero
  2. one
  3. two
  4. few
  5. many
  6. other

For more information about plurals, check the following official document.

https://developer.android.com/guide/topics/resources/string-resource.html#Plurals

 

Thanks.

Posted in Uncategorized

Android Percentage Layouts

Hi Developers,

Today we will learn how  to support percentage based dimensions in Android app.

Follow these steps to make the basic setup

  • Create the new project in Android Studio
  • Create the blank Activity MainActivity
  • Now you should have MainActivity.java and activity_main.xml in the layout folder.
  • Percentage Layout support comes in Percent Support Lib
  • Edit your build.gradle and add the following line in dependencies
compile 'com.android.support:percent:23.3.0'

Now you are ready with the basic setup to use the Percentage based layout in your app.

The Percent package provides APIs to support adding and managing percentage based dimensions in your app.

We will use  android.support.percent.PercentRelativeLayout as a root of our activity_main.xml

Edit the activity_main.xml and add the following code


<android.support.percent.PercentRelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="touchscreen.percentlayouthelper.MainActivity">
    <TextView
        app:layout_widthPercent="50%"
        app:layout_heightPercent="50%"
        android:background="@android:color/holo_orange_dark"
        android:id="@+id/layout_one"
        android:gravity="center"
        android:textColor="#ffffff"
        android:textStyle="bold"
        android:text="@string/layout_percent_one"/>
    <TextView
        app:layout_widthPercent="50%"
        app:layout_heightPercent="50%"
        android:background="@android:color/holo_blue_light"
        android:id="@+id/layout_two"
        android:layout_toRightOf="@id/layout_one"
        android:text="@string/layout_percent_one"
        android:gravity="center"
        android:textStyle="bold"
        android:textColor="#ffffff"/>
    <TextView
        app:layout_widthPercent="100%"
        app:layout_heightPercent="50%"
        android:background="@android:color/holo_purple"
        android:id="@+id/layout_three"
        android:layout_below="@id/layout_two"
        android:text="@string/layout_percent_three"
        android:gravity="center"
        android:textStyle="bold"
        android:textColor="#ffffff"/>
</android.support.percent.PercentRelativeLayout>

We have put three TextView in the layout relative to each other.

On the upper half of the screen we have added two TextView and on the lower half we have added one TextView.

As you can see have not set layout_width and layout_height, instead we are using  layout_widthPercent and layout_heightPercent

The dimensions for the view are as follows

  1. First TextView has 50% width and 50% height
  2. Second TextView has 50% width and 50% height
  3. Third   TextView has 100% width and 50% height

Now run the project and you can see the following output.

percentage_layout

We have added different colors as a background to the TextView for better identification of the TextView size.

You can use the following attributes to the Views in the PercentRelativeLayout

  • layout_widthPercent
  • layout_heightPercent
  • layout_marginPercent
  • layout_marginLeftPercent
  • layout_marginTopPercent
  • layout_marginRightPercent
  • layout_marginBottomPercent
  • layout_marginStartPercent
  • layout_marginEndPercent
  • layout_aspectRatio

You can download PercentLayoutHelper the full source code and android studio project.

Thanks!

Posted in advanced

Android Circular TextView

Hello Developers,

While developing the Android applications, we might need to show some text in the circle.

Android does not provide the Circular TextView. So we will create the Circular TextView by applying the XML drawable as a background to TextView.

Follow these steps to create the Circular TextView

  • Create the new project in Android Studio and name it CircularTextview
  • Create the blank Activity MainActivity
  • Now you should have MainActivity.java and activity_main.xml in the layout folder.
  • Now we need to create some xml drawable files.
  • Create the file state_normal.xml and add the following code in it.

<?xml version=”1.0″ encoding=”utf-8″?>
<shape xmlns:android=”http://schemas.android.com/apk/res/android”>
<solid android:color=”@color/color_state_normal” />
<size android:height=”130dp”
android:width=”130dp”/>
<corners
android:topLeftRadius=”65dp”
android:topRightRadius=”65dp”
android:bottomLeftRadius=”65dp”
android:bottomRightRadius=”65dp”/>
</shape>

There are few important points to here in the xml.

  1. We have defined the drawable as shape in the xml.
  2. The solid tag defines that we need to fill the shape with the color  “color_state_normal”.
  3. The size tag defines the height and width of the shape, in this case it is 130dp each.
  4. Next the very important part, we have defined the corners of the the shape in terms of radius.
  5. Note that we have kept each corner exactly half of the width or height. This is the most important part for the shape to be Circular, otherwise we will not get exact circle shape.
  • Now add another xml state_pressed.xml and add the following code in it.

<?xml version=”1.0″ encoding=”utf-8″?>
<shape xmlns:android=”http://schemas.android.com/apk/res/android”>
<solid android:color=”@color/color_state_pressed” />
<size android:height=”130dp”
android:width=”130dp”/>
<corners
android:topLeftRadius=”65dp”
android:topRightRadius=”65dp”
android:bottomLeftRadius=”65dp”
android:bottomRightRadius=”65dp”/>
</shape>

You should have noticed that we just have changed the color and rest of the things are same as state_normal.xml

  • By this time you must have got compilation error for the colors defined in both of the drawable xml files.
  • So lets add the colors.xml in values folder and dd the following lines in it.

<?xml version=”1.0″ encoding=”utf-8″?>
<resources>
<color name=”color_state_pressed”> #660099 </color>
<color name=”color_state_normal”> #6633CC </color>

</resources>

  • Now add another drawable xml selector.xml in drawable folder and add following code in it.

<?xml version=”1.0″ encoding=”utf-8″?>
<selector xmlns:android=”http://schemas.android.com/apk/res/android”>
<item android:state_pressed=”true” android:drawable=”@drawable/state_pressed”/>
<item android:state_focused=”true” android:drawable=”@drawable/state_normal”/>
<item android:state_window_focused=”true” android:drawable=”@drawable/state_normal”/>
</selector>

Here we are simply defining which drawable to draw in which state, in pressed state we are showing         state_pressed drawable and in focused state we are showing state_normal drawable.

  • Now go to the activity_main.xml and add the following code

<RelativeLayout 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:paddingLeft=”@dimen/activity_horizontal_margin”
android:paddingRight=”@dimen/activity_horizontal_margin”
android:paddingTop=”@dimen/activity_vertical_margin”
android:paddingBottom=”@dimen/activity_vertical_margin” tools:context=”.MainActivity”
android:layout_centerInParent=”true”>

<TextView android:text=”@string/hello_world” android:layout_width=”130dp”
android:layout_height=”130dp”
android:background=”@drawable/selector”
android:gravity=”center”
android:layout_centerInParent=”true”
android:textStyle=”bold”
android:clickable=”true”
android:textColor=”@android:color/white”/>

</RelativeLayout>

We have defined the TextView and set the selector.xml as its background.

Now build and run the project and you can see the following output.

circular_textview

  • Additionally we can see the change in color when we tap on the circle.

You can download the whole Android Studio project CircularTextView

Posted in Custom Component