Android Basic Training Course: Creating a StackView

    Stack is a common design that we can see at fronted-end programming including mobile app development. When using Android phone, you can realize that showing "recent apps" is a type of stack view design:
    This design is very diverse but by this post, just about "Android basic development", I would like to talk about using StackView widget. Like ListView or GridView, it's a subclass of AdapterView, so it has the same operation mechanism (adapter of a "list" of object). Now, following this tutorial step by step, you will understand the way to use it!

Preparing some drawables resource

    The fact that stack view is usually used for display "stack of images" or something that similarity. So, after start a new Android Studio project, please add some own images to drawable folder. Make sure that these images have the same size:

Put StackView to your Activity layout

    Just including a StackView in your activity layout file like this:
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<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:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="info.devexchanges.stackview.MainActivity">

    <StackView
        android:id="@+id/stack_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true" />

</RelativeLayout>

Create layout for each StackView item

    As noted above, Stack view is usually used for display list of images, so I will make a layout which contains an ImageView to show a drawable resource and a TextView to present it's name for each StackView item like this:
item_stack.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" >

    <ImageView
        android:id="@+id/imageView"
        android:contentDescription="@null"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/image_1"
        android:layout_gravity="center_horizontal" />

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:layout_marginTop="@dimen/activity_horizontal_margin"
        android:textColor="@android:color/holo_blue_dark"
        android:textStyle="bold" />

</LinearLayout>

Create a POJO class

    Java object for each Stack view item:
StackItem.java
package info.devexchanges.stackview;

public class StackItem {

    private int drawableId;
    private String imageName;

    public StackItem(int id, String imageName) {
        this.imageName = imageName;
        this.drawableId = id;
    }

    public String getImageName() {
        return imageName;
    }

    public int getDrawableId() {
        return drawableId;
    }
}

Create a StackView adapter class

    This is the most important step of this tutorial. Like ListView, we can create a subclass of ArrayAdapter or BaseAdapter to build the adapter class which holding and displaying data. I also provide a ViewHolder to make convertView clearly:
StackAdapter.java
package info.devexchanges.stackview;

import android.annotation.SuppressLint;
import android.content.Context;
import android.support.annotation.NonNull;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;

import java.util.List;

public class StackAdapter extends ArrayAdapter<StackItem> {

    private List<StackItem> items;
    private Context context;

    public StackAdapter(Context context, int textViewResourceId, List<StackItem> objects) {
        super(context, textViewResourceId, objects);
        this.items = objects;
        this.context = context;
    }

    @NonNull
    @SuppressLint("InflateParams")
    public View getView(int position, View convertView, @NonNull ViewGroup parent) {
        ViewHolder holder; //initialize a null ViewHolder object
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        // If holder not exist then locate all view from UI file
        if (convertView == null) {
            // inflate UI from XML file
            convertView = inflater.inflate(R.layout.item_stack, parent, false);
            // get all UI view
            holder = new ViewHolder(convertView);
            // set tag for holder
            convertView.setTag(holder);
        } else {
            // if holder created, get tag from view
            holder = (ViewHolder) convertView.getTag();
        }
        StackItem stackItem = items.get(position);

        //set stack item data to views
        holder.image.setImageResource(stackItem.getDrawableId());
        holder.imageName.setText(stackItem.getImageName());

        return convertView;
    }

    private class ViewHolder {
        private TextView imageName;
        private ImageView image;

        public ViewHolder(View view) {
            this.image = (ImageView) view.findViewById(R.id.imageView);
            this.imageName = (TextView) view.findViewById(R.id.textView);
        }
    }
}

Activity programmatically code

    There is nothing special in the main activity code. Just initializing an adapter with available data and attaching it to the StackView:
MainActivity.java
package info.devexchanges.stackview;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.StackView;

import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {

    private final int[] IMAGE_IDs = {R.drawable.image_1, R.drawable.image_2, R.drawable.image_3,
            R.drawable.image_4, R.drawable.image_5, R.drawable.image_6};

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

        StackView stackView = (StackView) findViewById(R.id.stack_view);

        ArrayList<StackItem> stackItems = new ArrayList<>();
        for (int imageId : IMAGE_IDs) {
            String name = getResources().getResourceEntryName(imageId);
            stackItems.add(new StackItem(imageId, name));
        }

        StackAdapter stackAdapter = new StackAdapter(this, R.layout.item_stack, stackItems);
        stackView.setAdapter(stackAdapter);
    }
}

Running the application

    Our output will be like this:

The weakness of the "default" StackView

    This "official" widget of Android SDK has the biggest weakness is swipe listener is absent, detect this user action is not a easily. Selected item event still not working well, either. I recommend to use a third-party library to make this layout better in programming. These are some of them:
I also had a post about creating Swipe Card Stack, read this tutorial HERE!




Share


Previous post
« Prev Post
Next post
Next Post »