How to page/paginate a custom ListView with Images and Text.

In this example we will have a custom listview with images and text and we will paginate them using a next/previous type of pagination.

When the user clicks the next button we navigate over to the next page and when he clicks the previous button we navigate over to the previous page.

Video tutorial(ProgrammingWizards TV Channel)

Well we have a video tutorial as an alternative to this. If you prefer tutorials like this one then it would be good you subscribe to our YouTube channel. Basically we have a TV for programming where do daily tutorials especially android.

Android Custom ListView with Images and Text Next/Previous Pagination

Let’s see the full example.

Android ListView Pagination

XML Layouts

Lets start by looking at Layouts.

(a). activity_main.xml

This is our main activity layout.

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 
    
    
    android_layout_width="match_parent"
    android_layout_height="match_parent"
    tools_context="com.tutorials.hp.listviewpaging.MainActivity">

    <LinearLayout
        android_orientation="vertical"
        android_layout_width="344dp"
        android_layout_height="495dp"
        tools_layout_editor_absoluteY="8dp"
        tools_layout_editor_absoluteX="8dp">
        <ListView
            android_id="@+id/listview"
            android_layout_width="match_parent"
            android_layout_height="wrap_content"
            />
         <LinearLayout
            android_layout_weight="2"
            android_orientation="horizontal"
            android_layout_width="match_parent"
            android_layout_height="100dp">
            <Button
                android_id="@+id/prevBtn"
                android_text="Previous"
                android_background="@color/colorAccent"
                android_padding="10dp"
                android_layout_width="wrap_content"
                android_layout_height="wrap_content" />
            <Button
                android_id="@+id/nextBtn"
                android_text="Next"
                android_background="#009968"
                android_padding="10dp"
                android_layout_width="wrap_content"
                android_layout_height="wrap_content" />

        </LinearLayout>
    </LinearLayout>

</android.support.constraint.ConstraintLayout>

(b). model.xml

  • As the name suggests, this layout models our viewitem.
  • We define how each Card shall appear in our List.
  • So at the root level we have a CardView widget.
  • We can also customize our CardView by specifying cardCornerRadius,cardElevation,width,height etc.
  • Each Card shall comprise textviews and images.
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView 
    android_orientation="horizontal" android_layout_width="match_parent"
    
    android_layout_margin="5dp"
    card_view_cardCornerRadius="15dp"
    card_view_cardElevation="10dp"
    android_layout_height="200dp">

    <LinearLayout
         android_orientation="vertical"
        android_layout_width="match_parent"
        android_layout_height="match_parent">

        <TextView
            android_layout_width="wrap_content"
            android_layout_height="wrap_content"
            android_textAppearance="?android:attr/textAppearanceLarge"
            android_text="Galaxy"
            android_id="@+id/nameTxt"
            android_padding="10dp"
            android_textColor="@color/abc_btn_colored_borderless_text_material"
            android_layout_alignParentTop="true"/>
        <LinearLayout
            android_orientation="horizontal"
            android_layout_width="match_parent"
            android_layout_height="wrap_content">
            <ImageView
                android_id="@+id/galaxyImageview"
                android_layout_width="wrap_content"
                android_layout_height="wrap_content"
                android_layout_alignParentLeft="true"
                android_layout_alignParentTop="true"
                android_layout_marginLeft="24dp"
                android_src="@drawable/andromeda" />
            <TextView
                android_layout_width="wrap_content"
                android_layout_height="wrap_content"
                android_textAppearance="?android:attr/textAppearanceLarge"
                android_text="Description"
                android_id="@+id/descTxt"
                android_padding="10dp"/>
            <TextView
                android_layout_width="wrap_content"
                android_layout_height="wrap_content"
                android_textAppearance="?android:attr/textAppearanceLarge"
                android_text="Category"
                android_id="@+id/categoryTxt"
                android_textStyle="italic"
                android_textColor="@color/colorPrimary"
                android_layout_gravity="bottom"
                android_padding="10dp"/>
        </LinearLayout>

    </LinearLayout>
</android.support.v7.widget.CardView>

Java Code

(a). Galaxy.java

  • Our Galaxy class.
  • Is our data object.
  • Each galaxy has a name,description,image and category.
package com.tutorials.hp.listviewpaging;

public class Galaxy {

    private String name,description,category;
    private int image;
    /*
    - Our constructor.
     */
    public Galaxy(String name, String description, int image,String category) {
        this.name = name;
        this.description = description;
        this.image = image;
        this.category=category;
    }
    /*
    - Our getters and setters.
     */
    public String getName() {
        return name;
    }
    public String getDescription() {
        return description;
    }
    public int getImage() {
        return image;
    }
    public String getCategory() {
        return category;
    }
}

(b). DataHolder.java

Our DataHolder class.

  • Returns a static list of galaxies.
package com.tutorials.hp.listviewpaging;
import java.util.ArrayList;
import java.util.List;
public class DataHolder {
/*
- Return our List of galaxies.
*/
public static List<Galaxy> getGalaxies()
{
ArrayList<Galaxy> galaxies=new ArrayList<>();
Galaxy g=new Galaxy("Whirlpool",
"The Whirlpool Galaxy, also known as Messier 51a, M51a, and NGC 5194, is an interacting grand-design spiral Galaxy with a Seyfert 2 active galactic nucleus in the constellation Canes Venatici.",
R.drawable.whirlpool,"spiral");
galaxies.add(g);
g=new Galaxy("Ring Nebular",
"The Ring Nebula is a planetary nebula in the northern constellation of Lyra. Such objects are formed when a shell of ionized gas is expelled into the surrounding interstellar medium by a red giant star.",
R.drawable.ringnebular,"elliptical");
galaxies.add(g);
g=new Galaxy("IC 1011",
"C 1011 is a compact elliptical galaxy with apparent magnitude of 14.7, and with a redshift of z=0.02564 or 0.025703, yielding a distance of 100 to 120 Megaparsecs. Its light has taken 349.5 million years to travel to Earth.",
R.drawable.ic1011,"elliptical");
galaxies.add(g);
g=new Galaxy("Cartwheel",
"The Cartwheel Galaxy is a lenticular galaxy and ring galaxy about 500 million light-years away in the constellation Sculptor. It is an estimated 150,000 light-years diameter, and a mass of about 2.9–4.8 × 10⁹ solar masses; it rotates at 217 km/s.",
R.drawable.cartwheel,"irregular");
galaxies.add(g);
g=new Galaxy("Triangulumn",
"The Triangulum Galaxy is a spiral Galaxy approximately 3 million light-years from Earth in the constellation Triangulum",
R.drawable.triangulum,"spiral");
galaxies.add(g);
g=new Galaxy("Small Magellonic Cloud",
"The Small Magellanic Cloud, or Nubecula Minor, is a dwarf galaxy near the Milky Way. It is classified as a dwarf irregular galaxy.",
R.drawable.smallamgellonic,"irregular");
galaxies.add(g);
g=new Galaxy("Centaurus A",
" Centaurus A or NGC 5128 is a galaxy in the constellation of Centaurus. It was discovered in 1826 by Scottish astronomer James Dunlop from his home in Parramatta, in New South Wales, Australia.",
R.drawable.centaurusa,"elliptical");
galaxies.add(g);
g=new Galaxy("Ursa Minor",
"The Milky Way is the Galaxy that contains our Solar System." +
" The descriptive milky is derived from the appearance from Earth of the Galaxy – a band of light seen in the night sky formed from stars",
R.drawable.ursaminor,"irregular");
galaxies.add(g);
g=new Galaxy("Large Magellonic Cloud",
" The Large Magellanic Cloud is a satellite galaxy of the Milky Way. At a distance of 50 kiloparsecs, the LMC is the third-closest galaxy to the Milky Way, after the Sagittarius Dwarf Spheroidal and the.",
R.drawable.largemagellonic,"irregular");
galaxies.add(g);
g=new Galaxy("Milky Way",
"The Milky Way is the Galaxy that contains our Solar System." +
" The descriptive milky is derived from the appearance from Earth of the Galaxy – a band of light seen in the night sky formed from stars",
R.drawable.milkyway,"spiral");
galaxies.add(g);
g=new Galaxy("Andromeda",
"The Andromeda Galaxy, also known as Messier 31, M31, or NGC 224, is a spiral Galaxy approximately 780 kiloparsecs from Earth. It is the nearest major Galaxy to the Milky Way and was often referred to as the Great Andromeda Nebula in older texts.",
R.drawable.andromeda,"irregular");
galaxies.add(g);
g=new Galaxy("Messier 81",
"Messier 81 is a spiral Galaxy about 12 million light-years away in the constellation Ursa Major. Due to its proximity to Earth, large size and active galactic nucleus, Messier 81 has been studied extensively by professional astronomers.",
R.drawable.messier81,"elliptical");
galaxies.add(g);
g=new Galaxy("Own Nebular",
" The Owl Nebula is a planetary nebula located approximately 2,030 light years away in the constellation Ursa Major. It was discovered by French astronomer Pierre Méchain on February 16, 1781",
R.drawable.ownnebular,"elliptical");
galaxies.add(g);
g=new Galaxy("Messier 87",
"Messier 87 is a supergiant elliptical galaxy in the constellation Virgo. One of the most massive galaxies in the local universe, it is notable for its large population of globular clusters—M87 contains",
R.drawable.messier87,"elliptical");
galaxies.add(g);
g=new Galaxy("Cosmos Redshift",
"Cosmos Redshift 7 is a high-redshift Lyman-alpha emitter Galaxy, in the constellation Sextans, about 12.9 billion light travel distance years from Earth, reported to contain the first stars —formed ",
R.drawable.cosmosredshift,"irregular");
galaxies.add(g);
g=new Galaxy("StarBust",
"A starburst Galaxy is a Galaxy undergoing an exceptionally high rate of star formation, as compared to the long-term average rate of star formation in the Galaxy or the star formation rate observed in most other galaxies. ",
R.drawable.starbust,"irregular");
galaxies.add(g);
g=new Galaxy("Sombrero",
"Sombrero Galaxy is an unbarred spiral galaxy in the constellation Virgo located 31 million light-years from Earth. The galaxy has a diameter of approximately 50,000 light-years, 30% the size of the Milky Way.",
R.drawable.sombrero,"spiral");
galaxies.add(g);
g=new Galaxy("Pinwheel",
"The Pinwheel Galaxy is a face-on spiral galaxy distanced 21 million light-years away from earth in the constellation Ursa Major. ",
R.drawable.pinwheel,"spiral");
galaxies.add(g);
g=new Galaxy("Canis Majos Overdensity",
"The Canis Major Dwarf Galaxy or Canis Major Overdensity is a disputed dwarf irregular galaxy in the Local Group, located in the same part of the sky as the constellation Canis Major. ",
R.drawable.canismajoroverdensity,"irregular");
galaxies.add(g);
g=new Galaxy("Virgo Stella Stream",
" Group, located in the same part of the sky as the constellation Canis Major. ",
R.drawable.virgostellarstream,"spiral");
galaxies.add(g);
return galaxies;
}
}

(c). CustomAdapter.java

Our CustomAdapter class.

  • Derives from android.widget.BaseAdapter.
  • Responsible for layout inflation as well as data binding to inflated views.
package com.tutorials.hp.listviewpaging;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.ArrayList;
public class CustomAdapter extends BaseAdapter {
Context c;
ArrayList<Galaxy> galaxies;
public CustomAdapter(Context c, ArrayList<Galaxy> galaxies) {
this.c = c;
this.galaxies = galaxies;
}
@Override
public int getCount() {
return galaxies.size();
}
@Override
public Object getItem(int i) {
return galaxies.get(i);
}
@Override
public long getItemId(int i) {
return i;
}
@Override
public View getView(int i, View view, ViewGroup viewGroup) {
if(view==null)
{
view= LayoutInflater.from(c).inflate(R.layout.model,viewGroup,false);
}
//reference widgets
TextView nameTxt=view.findViewById(R.id.nameTxt);
TextView descTxt=view.findViewById(R.id.descTxt);
TextView categoryTxt=view.findViewById(R.id.categoryTxt);
ImageView galaxyImg=view.findViewById(R.id.galaxyImageview);
//bind data to widgets
Galaxy g= (Galaxy) getItem(i);
nameTxt.setText(g.getName());
descTxt.setText(g.getDescription());
categoryTxt.setText(g.getCategory());
galaxyImg.setImageResource(g.getImage());
return view;
}
}

(d). Paginator.java

Our Paginator class.

  • Will page our data.
package com.tutorials.hp.listviewpaging;
import java.util.ArrayList;
public class Paginator {
public static final int TOTAL_NUM_ITEMS = DataHolder.getGalaxies().size();
public static final int ITEMS_PER_PAGE = 5;
/*
- Our constructor class.
*/
public Paginator() {
}
/*
TOTAL NUMBER OF PAGES
*/
public int getTotalPages() {
int remainingItems=TOTAL_NUM_ITEMS % ITEMS_PER_PAGE;
if(remainingItems>0)
{
return TOTAL_NUM_ITEMS / ITEMS_PER_PAGE;
}
return (TOTAL_NUM_ITEMS / ITEMS_PER_PAGE)-1;
}
/*
CURRENT PAGE's GalaxieS LIST
*/
public ArrayList<Galaxy> getCurrentGalaxys(int currentPage) {
int startItem = currentPage * ITEMS_PER_PAGE;
int lastItem = startItem + ITEMS_PER_PAGE;
ArrayList<Galaxy> currentGalaxys = new ArrayList<>();
//LOOP THRU LIST OF GALAXIES AND FILL CURRENTGALAXIES LIST
try {
for (int i = 0; i < DataHolder.getGalaxies().size(); i++) {
//ADD CURRENT PAGE'S DATA
if (i >= startItem && i < lastItem) {
currentGalaxys.add(DataHolder.getGalaxies().get(i));
}
}
return currentGalaxys;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}

(e). MainActivity.java

Our MainActivity class.

  • Our widgets will be a listview and two buttons: next and previous.
  • We instantiate our Paginator here and page data.
  • We toggle button states depending on current page.
package com.tutorials.hp.listviewpaging;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.ListView;
public class MainActivity extends AppCompatActivity {
ListView listView;
Button nextBtn, prevBtn;
Paginator p = new Paginator();
private int totalPages =p.getTotalPages();
private int currentPage = 0;
CustomAdapter adapter;
/*
- When activity is created
*/
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
this.initializeViews();
this.bindData(currentPage);
prevBtn.setEnabled(false);
//NAVIGATE
nextBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
currentPage += 1;
bindData(currentPage);
toggleButtons();
}
});
prevBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
currentPage -= 1;
bindData(currentPage);
toggleButtons();
}
});
}
/*
- Initialize ListView.
*/
private void initializeViews()
{
listView= (ListView) findViewById(R.id.listview);
nextBtn = (Button) findViewById(R.id.nextBtn);
prevBtn = (Button) findViewById(R.id.prevBtn);
}
/*
- Bind data to ListView.
*/
private void bindData(int page) {
adapter=new CustomAdapter(this,p.getCurrentGalaxys(page));
listView.setAdapter(adapter);
}
/*
- Toggle button states
*/
private void toggleButtons() {
//SINGLE PAGE DATA
if (totalPages <= 1) {
nextBtn.setEnabled(false);
prevBtn.setEnabled(false);
}
//LAST PAGE
else if (currentPage == totalPages) {
nextBtn.setEnabled(false);
prevBtn.setEnabled(true);
}
//FIRST PAGE
else if (currentPage == 0) {
prevBtn.setEnabled(false);
nextBtn.setEnabled(true);
}
//SOMEWHERE IN BETWEEN
else if (currentPage >= 1 && currentPage <= totalPages) {
nextBtn.setEnabled(true);
prevBtn.setEnabled(true);
}
}
}
Download

You can download the full source code below or watch the video from the link provided.

[sociallocker id=8131]
No. Location Link
1. GitHub [Download not found]
2. GitHub Browse
3. YouTube Video Tutorial
4. YouTube ProgrammingWizards TV Channel
5. Camposha View All ListView Tutorials
[/sociallocker]