How to Make Android Apps 3

How to Make Android Apps Android ListViewsIn this part of the tutorial I’ll cover Android ListViews, ArrayAdapters, Custom Array Adapters, ListAdapter, LayoutInflator, ImageView, and a great deal about terminology that confuses people.

To learn how Android Studio works look here at my Android Studio tutorial. If you missed the first part of this tutorial it is here How to Make Android Apps. All of the code used follows the video below.

If you like videos like this, it helps me if you share it on Google Plus with a click here

Code From the Video

The first 2 files are for the first easy ListView example. The rest of the files are for the last 2 examples.

Main_Activity.java

package com.newthinktank.listviewexample.app;

import android.app.Activity;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.Toast;


public class MainActivity extends ActionBarActivity {

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

        // Simple array with a list of my favorite TV shows
        String[] favoriteTVShows = {"Pushing Daisies", "Better Off Ted",
        "Twin Peaks", "Freaks and Geeks", "Orphan Black", "Walking Dead",
        "Breaking Bad", "The 400", "Alphas", "Life on Mars"};

        // The ListAdapter acts as a bridge between the data and each ListItem
        // You fill the ListView with a ListAdapter. You pass it a context represented by
        // this. A Context provides access to resources you need.
        // android.R.layout.simple_list_item_1 is one of the resources needed.
        // It is a predefined layout provided by Android that stands in as a default

        ListAdapter theAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1,
                favoriteTVShows);

        // ListViews display data in a scrollable list
        ListView theListView = (ListView) findViewById(R.id.theListView);

        // Tells the ListView what data to use
        theListView.setAdapter(theAdapter);

        theListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {

                String tvShowPicked = "You selected " +
                        String.valueOf(adapterView.getItemAtPosition(i));

                Toast.makeText(MainActivity.this, tvShowPicked, Toast.LENGTH_SHORT).show();

            }
        });
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
}

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:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:orientation="vertical"
    tools:context="com.newthinktank.listviewexample.app.MainActivity">

    <ListView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/theListView"></ListView>

</LinearLayout>

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:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:orientation="vertical"
    tools:context="com.newthinktank.listviewexample2.app.MainActivity">

    <ListView
        android:id="@+id/listView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</LinearLayout>

MainActivity.java

package com.newthinktank.listviewexample2.app;

import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ArrayAdapter;
import android.widget.ListAdapter;
import android.widget.ListView;


public class MainActivity extends ActionBarActivity {

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

        // Simple array with a list of my favorite TV shows
        String[] favoriteTVShows = {"Pushing Daisies", "Better Off Ted",
                "Twin Peaks", "Freaks and Geeks", "Orphan Black", "Walking Dead",
                "Breaking Bad", "The 400", "Alphas", "Life on Mars"};

        // A View is the generic term and class for every widget you put on your screen.
        // Views occupy a rectangular area and are responsible for handling events
        // and drawing the widget.

        // The ListAdapter acts as a bridge between the data and each ListItem
        // You fill the ListView with a ListAdapter. You pass it a context represented by
        // this.

        // A Context provides access to resources you need. It provides the current Context, or
        // facts about the app and the events that have occurred with in it.
        // android.R.layout.simple_list_item_1 is one of the resources needed.
        // It is a predefined layout provided by Android that stands in as a default

         ListAdapter theAdapter = new ArrayAdapter<String>(this, R.layout.row_layout,
            R.id.textView1, favoriteTVShows);

        // We point the ListAdapter to our custom adapter
        // ListAdapter theAdapter = new MyAdapter(this, favoriteTVShows);

        // Get the ListView so we can work with it
        ListView theListView = (ListView) findViewById(R.id.listView1);

        // Connect the ListView with the Adapter that acts as a bridge between it and the array
        theListView.setAdapter(theAdapter);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
}

MyAdapter.java

package com.newthinktank.listviewexample2.app;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;

// We can create custom adapters
class MyAdapter extends ArrayAdapter<String> {

    public MyAdapter(Context context, String[] values){

        super(context, R.layout.row_layout_2, values);

    }

    // Override getView which is responsible for creating the rows for our list
    // position represents the index we are in for the array.

    // convertView is a reference to the previous view that is available for reuse. As
    // the user scrolls the information is populated as needed to conserve memory.

    // A ViewGroup are invisible containers that hold a bunch of views and
    // define their layout properties.
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        // The LayoutInflator puts a layout into the right View
        LayoutInflater theInflater = LayoutInflater.from(getContext());

        // inflate takes the resource to load, the parent that the resource may be
        // loaded into and true or false if we are loading into a parent view.
        View theView = theInflater.inflate(R.layout.row_layout_2, parent, false);

        // We retrieve the text from the array
        String tvShow = getItem(position);

        // Get the TextView we want to edit
        TextView theTextView = (TextView) theView.findViewById(R.id.textView1);

        // Put the next TV Show into the TextView
        theTextView.setText(tvShow);

        // Get the ImageView in the layout
        ImageView theImageView = (ImageView) theView.findViewById(R.id.imageView1);

        // We can set a ImageView like this
        theImageView.setImageResource(R.drawable.dot);

        return theView;

    }
}

row_layout.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">

    <!-- Used to define a custom ListView row -->

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="30sp"
        android:textStyle="bold"
        android:padding="15dp"
        />

</LinearLayout>

row_layout_2.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="horizontal">

    <!-- Image for each ListItem row
    We can refer to images in our drawable folder with
    @drawable/dot for the image named dot.png -->
    <ImageView
        android:id="@+id/imageView1"
        android:layout_width="25dp"
        android:layout_height="25dp"
        android:layout_marginLeft="10dp"
        android:layout_marginTop="25dp"
        android:src="@drawable/dot"/>
    
    <!-- Used to define a custom ListView row -->
    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="30sp"
        android:textStyle="bold"
        android:padding="15dp"
        />

</LinearLayout>

Presentation Slides

Click the images below to view them full screen

Android ListView

Android ListView

Android ListView 3

Android ListView 4

14 Responses to “How to Make Android Apps 3”

  1. bob says:

    Thanks for tutorial. Beginner Question:

    Why did you need to set up

    theImageView.setImageResource(R.drawable.dot);

    Is not in xml already ?

  2. Mike says:

    Hi Derek – Awesome tutorials, they’ve been a great help with the app I’m working on. I know it might be a little more advanced, but I was wondering if you’d be able to touch on using AsyncTask to get data from a web service to use for populating a ListView. I’m able to successfully get the data I need from my web service API, but I’m a little stuck on how to connect this back to the ArrayAdapter given the separation between the UI thread and the AsyncTask. I can see in the logs I have my data, but it seems to overall be hanging when going back to the UI and displaying of the data into the ListView. Thanks!

  3. Paul says:

    Hi,

    Thanks for the great tutorial.

    After we changed from using android.R.layout.simple_list_item_1 to using our own layout R.layout.row_layout, the program wouldn’t run and I got the error “android.widget.LinearLayout cannot be cast to android.widget.TextView” and I can’t figure out what I did different to you.

    Any thoughts?

    I carried on after that and created the new layout and the adapter and the app worked fine.

    Thanks again for the tutorials.

  4. Mohit Saxena says:

    Hey Derek,

    Thanks for these awesome tutorials, extremely good for beginners like myself.

    I have a question regarding the part where you introduce us to use the customized row design (starting at time 9:46 of video), you told to use LinearLayout with the Text view to create row design. However this didn’t work out for me and I am getting compile time error that id for TextView is not found. I have setup it up correctly but it didn’t work out for me.

    Instead, when I removed the LinearLayout and customised just with TextView, it worked out. Can you please help me understand that why could have that happened?

  5. Mohit Saxena says:

    Basically, I got same error what Paul has mentioned above. I have yet to check with your code, but I am pretty sure that I have done exactly same what you told in video. Android Studio version 0.8.6.

    Since it didn’t explicitly provide option to change the target sdk, all my tutorials app are targeted to Android L.

  6. Ivanco says:

    Hey Derek,

    Great job on the tutorials, I’ve been following you for a while now and I wanna say thanks, you are awesome!
    btw I just want to mention a difference between the code in the video and on your site.
    [MainActiivity.java line 37]

    ListAdapter theAdapter = new ArrayAdapter(this, R.layout.row_layout,
    R.id.textView1, favoriteTVShows);

    And [in your video]

    ListAdapter theAdapter = new MyAdapter(this, favoriteTVShows);

    • Derek Banas says:

      Thank you for the compliment 🙂 I’ll take a look at the code, but normally what I post on my website is perfect. I used to slip up in the videos in the past every once in a while.

  7. János says:

    Hey Derek!

    Thanks for your work. A try to follow step by step these tutorials and I got an error like Paul (7. September)

    “android.widget.LinearLayout cannot be cast to android.widget.TextView”

    The problem is that your video does not contain the step, when you wrote “R.id.textView1,”.

    Although the correct code on your website contains it.

    ListAdapter theAdapter = new ArrayAdapter(this, R.layout.row_layout, R.id.textView1, favoriteTVShows);

    I hope it can help for others, who have got the same error.

    Thaks again for these tutorials!

    János

Leave a Reply

Your email address will not be published.

Google+