Friday, 30 June 2017

Android: Sending headers with HttpURLConnection

This post includes the usage and implementation of HttpURLConnection to download a file from a URL along with sending the required headers with the http request. Through this post you will also learn to send custom headers along with the request to your http url.

The usage and implementation of HttpURLConnection is very simple as follows:

1. In your project, just add the following method where you want to download the file. Just pass the url from which you want to download the file, as the parameter to the below method.

private void downloadFileFromHttpURL(String your_url){
            
            URL url = new URL(your_url);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();

            // default headers for the request
            connection.addRequestProperty("Content-Type", "application/json");

            // custom headers for the request
            connection.addRequestProperty("customHeaderKey1", "HEADER_VALUE");
            connection.addRequestProperty("customHeaderKey2", "HEADER_VALUE");

            // check for the connection of url
            int response = connection.getResponseCode();
            if (response == 200) { // connected to the URL
LogWriter.write("LOG_TAG", "Is downloading..?");     

BufferedInputStream inStream = new BufferedInputStream(connection.getInputStream());
                // provide the path to save the downloaded file
                FileOutputStream fileStream = new FileOutputStream("YOUR_FILE_PATH");

                // BufferesOutputStream is used to write the downloaded file
                BufferedOutputStream outStream = new BufferedOutputStream(fileStream);

                byte[] buffer = new byte[16384];
                int len = 0;
                while ((len = inStream.read(buffer, 0, 16384)) != -1) {
                    LogWriter.write("LOG_TAG", "Yes downloading..");
                    outStream.write(buffer, 0, len);
                }
                outStream.flush();
                inStream.close();
                outStream.close();
            } else {
                // disconnect from URL if not connected  
                connection.disconnect();
                return null;
            }
            // disconnect from URL when the download is completed  
            connection.disconnect();
    }

That's all.
The above method will download the file from the url and save it to the path provided by you.
There are other option as well that you can use with HttpURLConnection which are follows:
   
      connection.setUseCaches(false);
      connection.setDoInput(true);
      connection.setDoOutput(true);
      connection.setRequestMethod("POST");

Note:
HttpURLConnection uses the GET method by default. It will use POST if setDoOutput(true) has been called.
Other HTTP methods (OPTIONS, HEAD, PUT, DELETE and TRACE) can be used with setRequestMethod(String).


Share and comment if any issues.

Monday, 26 June 2017

Android: Add and remove view dynamically

In this post I will show you how to add and remove a view dynamically at run-time.
This will be explained in a very simple activity in which when you will click the Add button, a new View will be added in the main layout(screen visible to you), and when you will click the Remove button, the newly added view will be removed from the main layout.


1. First of all make a layout class for the view which you want to inflate at run time. Here I'm naming it as row.xml and add the following code to it:

<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="wrap_content">
    <Button
        android:id="@+id/remove"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:text="Remove"/>
    <TextView
        android:id="@+id/textout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_toLeftOf="@+id/remove"/>
</RelativeLayout>


2. Now in the MainActivity.java class just add the below code snippet:

public class MainActivity extends Activity {

 EditText textIn;
 Button buttonAdd;
 LinearLayout container;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  textIn = (EditText)findViewById(R.id.textin);
  buttonAdd = (Button)findViewById(R.id.add);
  container = (LinearLayout)findViewById(R.id.container);
  
  buttonAdd.setOnClickListener(new OnClickListener(){

   @Override
   public void onClick(View arg0) {
// code to inflate the view to be added at run time (row.xml)    
LayoutInflater layoutInflater = 
      (LayoutInflater) getBaseContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    final View addView = layoutInflater.inflate(R.layout.row, null);
    TextView textOut = (TextView)addView.findViewById(R.id.textout);
    textOut.setText(textIn.getText().toString());
    Button buttonRemove = (Button)addView.findViewById(R.id.remove);
    buttonRemove.setOnClickListener(new OnClickListener(){

     @Override
     public void onClick(View v) {
      ((LinearLayout)addView.getParent()).removeView(addView);
     }});
    
    container.addView(addView);
   }});
  
 }
}

3. The layout file for MainActivity.java class named activity_main.xml:

<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:orientation="vertical" >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/hello_world" />
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <Button
            android:id="@+id/add"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:text="Add"/>
        <EditText
            android:id="@+id/textin"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_toLeftOf="@+id/add"/>
    </RelativeLayout>
    <LinearLayout 
        android:id="@+id/container"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">
    </LinearLayout>

</LinearLayout>

That's all. Compile and run the app and after pressing the Add button you can see that a new view is added below to the Add button.


Share and comment if any issue.

Sunday, 18 June 2017

Android: ExpandableListView item click in Activity

In this post I will show the implementation of getting the item click event of ExpandableListview in your calling Activity or Fragment.
ExpandableListView is used to group list data by categories.It is a view that shows items in a vertically scrolling two-level list. It differs from a ListView by allowing two levels which are groups that can be easily expanded and collapsed by touching to view and their respective children items.
If you are not familiar with using ExpandableListView, first refer the tutorial here.

Now to get the item click in your activity or fragment follow below steps:

1. First make an Interface for the connectivity of your item click in your activity. For this create a class IExpandableListItemClick.java and add the following code:

public interface IExpandableListItemClick {

    void onExpandedItemClick(View view, int position);

}

2. In your adapter class make a variable for your Interface as follows:

 private IExpandableListItemClick expandedItemClickListener;

3. Now in the constructor of your adapter class assign your interface as follows:

public ExpandableListAdapter(Context context, List<String> expandableListTitle, HashMap<String, String>> expandableListDetail,
                          IExpandableListItemClick listener) {
        this.context = context;
               ................                                             
        this.expandedItemClickListener = listener;
    }


4. Now in the getChildView method of your adapter class add the following code:

 @Override
    public View getChildView(int listPosition, int expandedListPosition, boolean isLastChild, View convertView, ViewGroup parent) {
        LayoutInflater inflater = LayoutInflater.from(context);
        convertView = inflater.inflate(R.layout.item_child_expandable_list, parent, false);
        
        // declare and initialize your view here

        convertView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                expandedItemClickListener.onExpandedItemClick(view, expandedListPosition);
            }
        });
        return convertView;
    }

5. Now in your activity or your fragment implement your interface as follows: I am using a fragment
and implement its method.

public class MainFragment extends Fragment implements IExpandableListItemClick {

@Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_main, container, false);
                                                     
          .......... ...............                 
                                                     
        return rootView;
    }                            
  ..... .........                 

@Override
    void onExpandedItemClick(View view, int position){   
                                                                                             
     }                                                                                      
 ...........                                                                                 
                                                                                             
}                

6. Now in the above method add a toast to see which item is clicked as follows:

@Override
    void onExpandedItemClick(View view, int position){                        
        Toast.makeText(getActivity, "Clicked item position: "+ position, Toast.LENGTH_SHORT).show();  
                                                         
     }


7. Now run your code and you can see the correct position of the item clicked in the toast.
You can change the parameters in interface method according to your requirements.

That's all.
Share it and comment if any issues.

Sunday, 11 June 2017

Android: BigPictureStyle Notification

Now a days, you must have seen a notification from many android apps that contain a picture/image along with the message. This notification with a big image is known as BigPicturestyle Notifications. These notifications are generally used for the promotional purpose of some brand or some product or you can say about an offer.
With help of V4 appcompat library, we can implement this for all devices from Android 2.0 onward.
Building this type of notification in android is very simple and can be implemented as follows:

1. First create Notification object and set the title, content text, ticker text etc as follows:
        
        //Create notification object and set the content.
        NotificationCompat.Builder nb= new NotificationCompat.Builder(this);
        nb.setSmallIcon(R.drawable.small_icon);
        nb.setContentTitle("Notification title");
        nb.setContentText("Notification content/message");
        nb.setTicker("Notification ticker text");

2. Now create a bitmap of the image which needs to be shown as big picture & set it as shown in below code. Set the summaryText, this will appear on expanding the notification.
        
        //get the bitmap to show in notification bar
        Bitmap bm = BitmapFactory.decodeResource(this.getResources(),R.drawable.big_icon);
        NotificationCompat.BigPictureStyle s = new NotificationCompat.BigPictureStyle().bigPicture(bm);
        s.setSummaryText("Notification text that appears on expanding the notification");
        nb.setStyle(s);

3. Now set the intent that should be launched on clicking on the notification.
        Intent resultIntent = new Intent(this, MainActivity.class);
        TaskStackBuilder taskBuilder = TaskStackBuilder.create(this);
        taskBuilder.addParentStack(MainActivity.class);
       
        // Adds the Intent that starts the Activity to the top of the stack
        taskBuilder.addNextIntent(resultIntent);
        PendingIntent resultPendingIntent =
                taskBuilder.getPendingIntent(0,PendingIntent.FLAG_UPDATE_CURRENT);
        nb.setContentIntent(resultPendingIntent);
        nb.setAutoCancel(true);
        NotificationManager mNotificationManager =
                (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
        // mId allows you to update the notification later on.
        mNotificationManager.notify(11221, nb.build());

That's all.
Share and comment if any issues.


Sunday, 4 June 2017

Android: CoordinatorLayout

In this post I will let you know about the new layout introduced in Android Design Support Library.
The CoordinatorLayout is a super-powered FrameLayout. It is similar to Frame Layout yet its behavior attribute makes it different from other layouts. If you have used a FrameLayout before, you should be very comfortable using CoordinatorLayout. If you haven’t used a FrameLayout, do not worry, it is pretty straightforward.

CoordinatorLayout is intended for two primary use cases:
- As a top-level application decor or chrome layout
- As a container for a specific interaction with one or more child views

By specifying Behaviors for child views of a CoordinatorLayout you can provide many different interactions within a single parent and those views can also interact with one another. View classes can specify a default behavior when used as a child of a CoordinatorLayout using the DefaultBehavior annotation.

Behaviors may be used to implement a variety of interactions and additional layout modifications ranging from sliding drawers and panels to swipe-dismissable elements and buttons that stick to other elements as they move and animate.

Children of a CoordinatorLayout may have an anchor. This view id must correspond to an arbitrary descendant of the CoordinatorLayout, but it may not be the anchored child itself or a descendant of the anchored child. This can be used to place floating views relative to other arbitrary content panes.

Children can specify insetEdge to describe how the view insets the CoordinatorLayout. Any child views which are set to dodge the same inset edges by dodgeInsetEdges will be moved appropriately so that the views do not overlap.

-Dependency:
For using CoordinatorLayout in you app import Android Support Library into your project, by adding the following dependency to your app build.gradle file:

           dependencies {
               ......
                   compile 'com.android.support:design:23.0.0'
          }

Above Support Library also includes others views namely Snackbar, CollapsingToolbar, FloatingActionButton etc out of which some of them we will be using today.

1. To show the use of CoordinatorLayout, we will simply make layout containing a FAB button which will automatically slides out of the way when a Snackbar is displayed. The CoordinatorLayout is the root layout. Within it, we have a button, that is centered on screen, and a FAB, that’s positioned at the bottom right of the screen, with a little margin to ensure we abide by the material design guidelines.
The layout class is as follows:

<android.support.design.widget.CoordinatorLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/coordinatorLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.sample.foo.usingcoordinatorlayout.FabAndSnackbarActivity">

    <Button
        android:id="@+id/showSnackbarButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:text="@string/show_snackbar"/>

    <android.support.design.widget.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|right"
        android:src="@android:drawable/ic_popup_disk_full"/>

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

2. Now create a class FabAndSnackbarActivity.java and add the following code:

public class FabAndSnackbarActivity extends AppCompatActivity {

    private Button mShowSnackbarButton;
    private CoordinatorLayout mCoordinatorLayout;

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

        mCoordinatorLayout = (CoordinatorLayout) findViewById(R.id.coordinatorLayout);

        mShowSnackbarButton = (Button) findViewById(R.id.showSnackbarButton);
        mShowSnackbarButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(mCoordinatorLayout,
                        "This is a simple Snackbar", Snackbar.LENGTH_LONG)
                        .setAction("CLOSE", new View.OnClickListener() {
                            @Override
                            public void onClick(View v) {
                                // Custom action
                            }
                        }).show();
            }
        });
    }
}

3. Now compile it and run your program. You will observe that the FAB button automatically slides up and out of the way for the Snackbar, when it is shown, and slides down and back to it’s position, when the snackbar is exiting from view. 

That's all. Share and comment if any issues.


Saturday, 27 May 2017

Android: GridView as ExpandableListView Item

In this post I will show you how to use a GridView as the item of an ExpandableListView.
An ExpandableListView is a view that shows items in a vertically scrolling two-level list.
This differs from the ListView by allowing two levels: one are the groups and other are the child items. The Groups can individually be expanded to show its children.

Now the implementation of using a GridView as an item of ExpandableListView is as follows:

1. First of all make a custom gridView class named MyCustomGridView.java and add the following code snippet to it:

public class MyCustomGridView extends GridView {

    private final Context mContext;
    int mHeight;

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

    public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int desiredWidth = 100;
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        int width;
        // Measure Width
        if (widthMode == MeasureSpec.EXACTLY) {
            // Must be this size
            width = widthSize;
        } else if (widthMode == MeasureSpec.AT_MOST) {
            // Can't be bigger than...
            width = Math.min(desiredWidth, widthSize);
        } else { // Be whatever you want
            width = desiredWidth;
        }
        // MUST CALL THIS
        setMeasuredDimension(width, mHeight);
        getGridViewSpanCount(width, mHeight);
    }

    public void setGridViewItemHeight(int height) {
        mHeight = height;
    }
}

2. Now make the layout file named gridview_item.xml which will be used as item of GridView:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <ImageView
        android:id="@+id/item_gridView_imgView"
        android:layout_width="@dimen/dimen_img_width"
        android:layout_height="@dimen/dimen_img_height"
        android:scaleType="centerCrop" />

    <TextView
        android:id="@+id/item_gridView_txtView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:maxLines="1"
        android:textAlignment="center"
        android:textColor="@color/black"
        android:textSize="16sp" />

</RelativeLayout>

3. Now make the adapter named MyCustomGridViewAdapter.java for setting the views in your gridView as follows:

public class MyCustomGridViewAdapter extends BaseAdapter {

    private Context mContext;
    private final ArrayList<YOUR_CLASS_TYPE> arrayList;

    public MyCustomGridViewAdapter(Context context, ArrayList<YOUR_CLASS_TYPE> arrayList) {
        this.mContext = context;
        this.arrayList = arrayList;
    }

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

    @Override
    public YOUR_CLASS_TYPE getItem(int position) {
        return arrayList.get(position);
    }

    @Override
    public long getItemId(int arg0) {
        return 0;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder = null;
        if (convertView == null) {
            LayoutInflater inflater = (LayoutInflater) mContext
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = inflater.inflate(R.layout.gridview_item, parent, false);
            holder = new ViewHolder();
            holder.text = (TextView) convertView.findViewById(R.id.item_gridView_txtView);
            holder.imageView = (ImageView) convertView.findViewById(R.id.item_gridView_imgView);
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }
        holder.text.setText(arrayList.get(position).getName());
  // Glide is the library used to laod an image into an imageView
        Glide.with(mContext).load(arrayList.get(position).getThumbnail_url())
                .asBitmap().centerCrop()
                .diskCacheStrategy(DiskCacheStrategy.SOURCE)
                .into(holder.imageView);
        return convertView;
    }

    private static class ViewHolder {
        TextView text;
        ImageView imageView;
    }
}

4. Now create a Fragment named ExpandableListViewFragment.java and add the following code snippet:

public class ExpandableListViewFragment extends Fragment implements GridViewItemClickInterface {

    private List<String> listDataHeader;
    private HashMap<String, ArrayList<YOUR_CLASS_TYPE>> listDataChild;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.layout_fragment_expandable_listvw, container, false);

        ExpandableListView mExpandablelistView = (ExpandableListView) rootView.findViewById(R.id.fragment_expandable_listview);
        prepareListData();
        CustomExpandableListAdapter mExpandableListAdapter = new CustomExpandableListAdapter(getActivity(), listDataHeader, listDataChild, this);
        mExpandablelistView.setAdapter(mExpandableListAdapter);
        mExpandablelistView.setOnGroupClickListener(new OnGroupClickListener() {
         @Override
         public boolean onGroupClick(ExpandableListView parent, View v, int groupPosition, long id) {
                // This way the expander cannot be collapsed
                // on click event of group item
                return false;
            }
        });
        return rootView;
    }

    private void prepareListData() {
        listDataHeader = new ArrayList<>();
        listDataHeader.add("Folder 1");
        listDataHeader.add("Folder 2");
        listDataChild = new HashMap<>();
        ArrayList<YOUR_CLASS_TYPE> details = new ArrayList<YOUR_CLASS_TYPE>();// fill the data as per your requirements
        listDataChild.put(listDataHeader.get(0), details);
        listDataChild.put(listDataHeader.get(1), null); // just to show null item view
    }

    @Override
    public void onGridViewItemClick(YOUR_CLASS_TYPE item) {
        Toast.makeText(getActivity(), "Currently selected is: " + item.getName(), Toast.LENGTH_SHORT).show();
    }
}

5. The layout file for the above fragment is as follows: layout_fragment_expandable_listvw.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:orientation="vertical">

        <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <ExpandableListView
            android:id="@+id/fragment_expandable_listview"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:divider="@color/transparent"
            android:listSelector="@color/transparent" />

    </RelativeLayout>

</LinearLayout>

6. Now create the adapter named CustomExpandableListAdapter.java file with the following code snippet:

public class CustomExpandableListAdapter extends BaseExpandableListAdapter {

    private Context mContext;
    private List<String> mListDataHeader;
    private HashMap<String, ArrayList<YOUR_CLASS_TYPE>> mListDataChild;
    private LayoutInflater mInflater;
    private GridViewItemClickInterface gridViewItemClickListener;
    private int columnsCount = 3;

    public CustomExpandableListAdapter(Context context, List<String> listDataHeader, HashMap<String, ArrayList<YOUR_CLASS_TYPE>> listChildData, GridViewItemClickInterface listener) {
        this.mContext = context;
        this.mListDataHeader = listDataHeader;
        this.mListDataChild = listChildData;
        this.mInflater = LayoutInflater.from(context);
        this.gridViewItemClickListener = listener;
    }

    @Override
    public int getGroupCount() {
        return mListDataHeader.size();
    }

    @Override
    public int getChildrenCount(int groupPosition) {
        return 1;
    }

    @Override
    public Object getGroup(int groupPosition) {
        return mListDataHeader.get(groupPosition);
    }

    @Override
    public Object getChild(int groupPosition, int childPosition) {
        return mListDataChild.get(this.mListDataHeader.get(groupPosition))
                .size();
    }

    @Override
    public long getGroupId(int groupPosition) {
        return groupPosition;
    }

    @Override
    public long getChildId(int groupPosition, int childPosition) {
        return childPosition;
    }

    @Override
    public boolean hasStableIds() {
        return false;
    }

    @Override
    public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
        String headerTitle = (String) getGroup(groupPosition);
        if (convertView == null) {
            // layout view of header group
            convertView = mInflater.inflate(R.layout.expandable_listvw_header, null);
        }
        TextView headerLabel = (TextView) convertView.findViewById(R.id.txtView_header);
        headerLabel.setTypeface(null, Typeface.BOLD);
        headerLabel.setText(headerTitle);
        return convertView;
    }

    @Override
    public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
        convertView = mInflater.inflate(R.layout.expandable_listvw_item, null);
        final ArrayList<YOUR_CLASS_TYPE> items = mListDataChild.get(mListDataHeader.get(groupPosition));
        if (items.size() > 0) {
            MyCustomGridView gridView = (MyCustomGridView) convertView.findViewById(R.id.item_custom_gridView);
            gridView.setNumColumns(columnsCount);
            gridView.setVerticalSpacing(10);
            gridView.setHorizontalSpacing(10);
            MyCustomGridViewAdapter adapter = new MyCustomGridViewAdapter(mContext, items);
            gridView.setAdapter(adapter);
            int totalHeight = 0;
// This is to get the actual size of gridView at runtime while filling the items into it
            for (int size = 0; size < adapter.getCount(); size++) {
                RelativeLayout relativeLayout = (RelativeLayout) adapter.getView(size, null, gridView);
                relativeLayout.measure(0, 0);
                totalHeight += relativeLayout.getMeasuredHeight();
            }
            gridView.setGridViewItemHeight(v);
            gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                    gridViewItemClickListener.onGridViewItemClick(items.get(position));
                }
            });
        } else {
            convertView = mInflater.inflate(R.layout.layout_blank, null);
        }

        return convertView;
    }

    @Override
    public boolean isChildSelectable(int groupPosition, int childPosition) {
        return true;
    }

}

7. The layout files for ExpandableListView group and item are as follows:
a) expandable_listvw_header.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="wrap_content"
    android:orientation="vertical">

    <TextView
        android:id="@+id/txtView_header"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textColor="@color/colorBlack"
        android:textSize="22sp" />

</LinearLayout>

b) expandable_listvw_item.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:orientation="vertical">

    <com.nishant.sample.ExpandableListPac.MyCustomGridView
        android:id="@+id/item_custom_gridView"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"/>

</LinearLayout>

c) layout_blank.xml - This is the layout to be shown when no items are available.

<?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:orientation="vertical">

    <TextView
        android:id="@+id/item_txt_no_items"
        android:layout_width="match_parent"
        android:layout_height="80dp"
        android:gravity="center_horizontal|center_vertical"
        android:text="No items available"
        android:textSize="22sp" />

</LinearLayout>

8. The interface class GridViewItemClickInterface.java is as follows:

public interface GridViewItemClickInterface {

    void onGridViewItemClick(YOUR_CLASS_TYPE item);
}

That's all. Now run your project and enjoy.

Share and comment if any issues.

Sunday, 21 May 2017

Android: Layout as background of view

In this post I will show you how to set your custom layout as the background of your item of your listview or gridview or any other view that contains long list of data, through your adapter.
This is very simple and can be done as follows:

1. Make a file custom_placeholder.xml of your custom layout as follows:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="140dp"
    android:layout_height="140dp"
    android:orientation="vertical">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_margin="6dp"
        android:background="@drawable/shape_bg">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:text="Downloading..."
            android:textAlignment="center"
            android:textSize="14sp" />

    </RelativeLayout>

</LinearLayout>


2. Now in the getView method of your adapter just replace your code with below code:

public View getView(final int position, View convertView, ViewGroup parent) {
        CustomViewHolder mViewHolder;
        if (convertView == null) {
            LayoutInflater layoutInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = layoutInflater.inflate(R.layout.item_gridview_assets, parent, false);
            mViewHolder = new CustomViewHolder(convertView);  // set your layout (convertView) as your viewHolder
            convertView.setTag(mViewHolder);
        } else {
            mViewHolder = (CustomViewHolder) convertView.getTag();
        }
          //Now check the condition whether your image is available or not  
        String value = imageList.get(position);
        if (!value.equalsIgnoreCase("")) {
             // case when image is available  
           mViewHolder.imgAssets.setBackgroundResource(R.drawable.sample_img);
        } else {
             // case when image is not available  
           // This will inflate your custom view that you created above
            LayoutInflater layoutInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = layoutInflater.inflate(R.layout.custom_placeholder, parent, false);
        }
        return convertView;
    }

That's all.
Share and comment if any issues.