Saturday 15 July 2017

HB Blog 140: Horizontal ListView In Android.

HorizontalListView is an Android List-view widget which scrolls in a horizontal manner (in contrast with the SDK-provided List View which scrolls vertically).

Basically, we extends Linear layout and use it as a container for views such as text view. This can be used as normal list view where selection and other list operations can be controlled via tagging the views with array positions.

Below is an tutorial, where I have added 10 list view items as text view in linear layout and created a custom class CustomHorizontalListView which can be used as an API for HorizontalListViewin Android.
Refer the below link for complete sample code:-

Download Sample Code

Have a look on few code snippets,

//custom_horizontallistview.xml
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
<?xml version="1.0" encoding="utf-8"?>
<HorizontalScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:scrollbars="none"
    android:layout_height="wrap_content">

    <LinearLayout
        android:id="@+id/ll_contatinerlistview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="5dp"
        android:layout_marginRight="5dp"
        android:orientation="horizontal"/>
</HorizontalScrollView>

//activity_main.xml
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
<com.harshalbenake.horizontallistview.views.CustomHorizontalListView
    android:id="@+id/customhorizontallistview"
    android:layout_width="match_parent"
    android:layout_margin="5dp"
    android:layout_height="match_parent"/>

</RelativeLayout>

//CustomHorizontalListView.java
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
package com.harshalbenake.horizontallistview.views;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;


import com.harshalbenake.horizontallistview.R;

import java.util.ArrayList;

/**
 * This class is used for custom HorizontalListView.
 */
public class CustomHorizontalListView extends LinearLayout {
    private Context mContext;
    private LinearLayout mll_contatinerlistview;
    private ArrayList<String> mItemSelectedArray;
    private String mItemArray[];
    public CustomHorizontalListView(Context context) {
        super(context);
        this.mContext = context;
        initlayout();
    }

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

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

    /**
     * initialize Layout
     */
    private void initlayout() {
        View rootView = inflate(mContext, R.layout.custom_horizontallistview, this);
        mll_contatinerlistview = (LinearLayout) rootView.findViewById(R.id.ll_contatinerlistview);
        mItemSelectedArray = new ArrayList<>();
    }

    /**
     * sets Lables
     * @param itemArray
     **/
    public void setListItems(String[] itemArray) {
        mItemArray=itemArray;
        for (int listItemsIndex = 0; listItemsIndex < itemArray.length; listItemsIndex++) {
            TextView view = new TextView(mContext);
            view.setId(listItemsIndex);
            view.setTag(itemArray[listItemsIndex]);
            view.setText(itemArray[listItemsIndex]);
            view.setBackgroundColor(Color.GRAY);
            view.setOnClickListener(new CustomOnClickListener());
            LayoutParams layoutParamsTextView = new LayoutParams(75, 500);
            layoutParamsTextView.setMargins(10,10,10,10);
            view.setGravity(Gravity.CENTER);
            view.setLayoutParams(layoutParamsTextView);
            mll_contatinerlistview.addView(view);
        }
    }

    /**
     * Custom On Click Listener
     */
    class CustomOnClickListener implements OnClickListener {

        public CustomOnClickListener() {
        }

        @Override
        public void onClick(View view) {
            int viewID = view.getId();
            String viewTag = view.getTag().toString();
            resetAllColors((ViewGroup)view.getParent());
            view.setBackgroundColor(Color.GREEN);
            mItemSelectedArray.clear();
            mItemSelectedArray.add(viewTag);
        }
    }

    public void resetAllColors(ViewGroup group)
    {
        for(int i = 0; i< mItemArray.length; i++){
            View view = group.getChildAt(i);
            view.setBackgroundColor(Color.GRAY);
        }
    }

    /**
     * selectd Item By Tag
     */
    public void selectItemByTag(String strTag){
        for(int i = 0; i< mItemArray.length; i++) {
            View view = mll_contatinerlistview.getChildAt(i);
            if(view.getTag().toString().equalsIgnoreCase(strTag)){
                view.setBackgroundColor(Color.GREEN);
                view.setSelected(true);
            }
        }
    }

    /**
     * gets Item Selected Array
     * @return
     */
    public ArrayList<String> getListItemsArray(){
        return mItemSelectedArray;
    }
}

//MainActivity.java  

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
package com.harshalbenake.horizontallistview;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import com.harshalbenake.horizontallistview.views.CustomHorizontalListView;

public class MainActivity extends AppCompatActivity {

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

        CustomHorizontalListView customhorizontallistview=(CustomHorizontalListView)findViewById(R.id.customhorizontallistview);
        String itemArray[]={"1","2","3","4","5","6","7","8","9","10"};
        customhorizontallistview.setListItems(itemArray);
    }
}

Saturday 1 July 2017

HB Blog 139: ProGuard - Shrinks, Optimizes, And Obfuscates Your Code.

The ProGuard tool shrinks, optimizes, and obfuscates your code by removing unused code and renaming classes, fields, and methods with semantically obscure names. The result is a smaller sized .apk file that is more difficult to reverse engineer. Because ProGuard makes your application harder to reverse engineer, it is important that you use it when your application utilizes features that are sensitive to security like when you are Licensing Your Applications.

ProGuard is integrated into the Android build system, so you do not have to invoke it manually. ProGuard runs only when you build your application in release mode, so you do not have to deal with obfuscated code when you build your application in debug mode. Having ProGuard run is completely optional, but highly recommended.
1. Shrinking – detects and removes unused classes, fields, methods, and attributes.
2. Optimization – analyzes and optimizes the bytecode of the methods.
3. Obfuscation – renames the remaining classes, fields, and methods using short meaningless names.

How to Enable Proguard in Android Studio ?
  • In Android Studio project, the minifyEnabled  property in the build.gradle file enables and disables Proguard for release builds.
  • The minifyEnabled property is part of the buildTypes release block that controls the settings applied to release builds.
  • The getDefaultProguardFile(‘proguard-android.txt’) method obtains the default Proguard settings from the Android SDK tools/proguard folder.
  • Android Studio adds the proguard-rules.pro file at the root of the module, which helps to add custom Proguard rules.