Martin
Martin

Reputation: 1191

custom ListView with text and image not showing up in Activity

I'm fairly new to Android and am trying to create a ListView with ImageView and TextView based on a custom adapter.

Somehow it won't seem to put the ListView on the screen when I try and run my app. No exceptions, though. Maybe I'm missing something very obvious. It would be great if someone could look over my code:

MyActivity.java:

public class MyActivity extends Activity {

    public static final String[] countries = new String[] {"Germany", "USA", "Great Britain", "Japan", "Korea"};
    public static final int[] images = new int[]{R.drawable.de, R.drawable.us, R.drawable.kr, R.drawable.jp, R.drawable.kr};
    ListView listView;
    List<MyListObject> values;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_my);
        TextView textView = (TextView) findViewById(R.id.textView);

        values = new ArrayList<MyListObject>();
        for (int i = 0; i < countries.length; i++) {
            MyListObject item = new MyListObject();
            item.setCountry(countries[i]);
            item.setImage(images[i]);
            values.add(item);
        }

        listView = (ListView) findViewById(R.id.list);
        MySimpleArrayAdapter adapter = new MySimpleArrayAdapter(this, R.layout.rowlayout, values);
        listView.setAdapter(adapter);

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.my, 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);
    }
}

MySimpleArrayAdapter.java:

public class MySimpleArrayAdapter extends ArrayAdapter<MyListObject> {
    private final Context context;
    private final List<MyListObject> values;

    public MySimpleArrayAdapter(Context context, int resourceID, List<MyListObject> values) {
        super(context, resourceID, values);
        this.context = context;
        this.values = values;
    }

    private class ViewHolder {
        ImageView imageView;
        TextView textView;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder;
        MyListObject rowItem = getItem(position);

        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        if (convertView == null) {
            convertView = inflater.inflate(R.layout.rowlayout, null);


        } else {
            holder = (ViewHolder) convertView.getTag();
        }
        holder = new ViewHolder();
        holder.textView = (TextView) convertView.findViewById(R.id.countryName);
        holder.imageView = (ImageView) convertView.findViewById(R.id.countryImage);


        holder.textView.setText(rowItem.getCountry());
        holder.imageView.setImageResource(rowItem.getImage());

        return convertView;
    }

    @Override
    public MyListObject getItem(int position) {
        return values.get(position);
    }

}

activity_my.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"
    tools:context=".MyActivity">

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:id="@+id/textView"/>

    <ListView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/list"
        android:layout_weight="1" />
</LinearLayout>

rowlayout.xml:

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal" android:layout_width="fill_parent"
    android:layout_height="wrap_content" android:gravity="center_vertical" >

    <ImageView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:paddingRight="10dp"
        android:id="@+id/countryImage" />
    <TextView
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:id="@+id/countryName"
        android:text="@+id/countryName" />

</LinearLayout>

MyListObject.java:

public class MyListObject {
    private int image;
    private String country;

    public int getImage() {
        return image;
    }

    public void setImage(int image) {
        this.image = image;
    }

    public String getCountry() {
        return country;
    }

    public void setCountry(String country) {
        this.country = country;
    }
}

Upvotes: 2

Views: 3985

Answers (5)

Trae Wright
Trae Wright

Reputation: 1

Make sure that your image width and height is not set to match constraints. Also, try updating the adapter in your main activity like this

public void updateAdapter(MyListObject _newObject){
    objectList.add(_newObject);
    adapter.notifyDataSetChanged();
}

Upvotes: 0

Kaushik
Kaushik

Reputation: 6162

In activity_my's top most linearlayout should have android:orientation="vertical" attribute

In your rowlayout parent layout is Horizontal LinearLayout and android:layout_width for both ImageView and TextView is fill_parent.So, only ImageView is visible as in LinearLayout child place linearly one by one.Change rowlayout like this

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:gravity="center_vertical"
    android:padding="8dp"
    android:orientation="horizontal" >

    <ImageView
        android:id="@+id/countryImage"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:paddingRight="10dp" />

    <TextView
        android:id="@+id/countryName"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="countryName" />

</LinearLayout>

You need to change your Adapter too

MySimpleArrayAdapter

public class MySimpleArrayAdapter extends ArrayAdapter<MyListObject> {
    private final Context context;
    private final List<MyListObject> values;
    private int resourceID;

    public MySimpleArrayAdapter(Context context, int resourceID, List<MyListObject> values) {
        super(context, resourceID, values);
        this.context = context;
        this.resourceID = resourceID;
        this.values = values;
    }

    private class ViewHolder {
        ImageView imageView;
        TextView textView;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder;       
        if (convertView == null) {
            LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = inflater.inflate(resourceID, null);
            holder = new ViewHolder();
            holder.textView = (TextView) convertView.findViewById(R.id.countryName);
            holder.imageView = (ImageView) convertView.findViewById(R.id.countryImage);
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }

        MyListObject rowItem = (MyListObject) values.get(position); 
        holder.textView.setText(rowItem.getCountry());
        holder.imageView.setImageResource(rowItem.getImage());

        return convertView;
    }

}

Screenshot :

enter image description here

Upvotes: 3

Blackbelt
Blackbelt

Reputation: 157437

the orientation of your LinearLayout should be vertical. Default is horizontal . Add

android:orientation="vertical"

to the LinearLayout that contains the ListView

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
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"
tools:context=".MyActivity">

this will probably fix your issue with the visualisation . On the other side there are a couple of things you can change to improve the performance.

  • In your layout you should provide 0dip as height, since you are providing the weight. That will help the framework at "onLayout" time.
  • ArrayAdapter has a concrete implementation of getItem(). You don't need to override it again, since you are already providing the dataset to the super class
  • You are using the ViewHolder pattern in the wrong way. You should instantiate the ViewHolder once, when the convertView is null, looks for the views (as you already did) and call convertView.setTag(viewHolderInstance),

Upvotes: 0

Pratik Dasa
Pratik Dasa

Reputation: 7439

Here below os my custom adapter class, refer it and do like that way, it will surely work.

private class EfficientAdapter extends BaseAdapter {

        private LayoutInflater mInflater;
        private Context context;
        JSONArray array;
        private Bitmap imageBitmap = null;

        public EfficientAdapter(Context context) {
            mInflater = LayoutInflater.from(context);
            this.context = context;
        }

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

        @Override
        public Object getItem(int arg0) {
            return null;
        }

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

        @Override
        public View getView(final int position, View convertView, ViewGroup parent) {

            final ViewHolder holder;

            if (convertView == null) {
                convertView = mInflater.inflate(R.layout.featured_item, null);
                holder = new ViewHolder();
                holder.txtTitle = (TextView) convertView.findViewById(R.id.txtTitle);
                holder.txtAuthorName = (TextView) convertView.findViewById(R.id.txtAuthorName);
                holder.txtDescription = (TextView) convertView.findViewById(R.id.txtDescription);
                convertView.setTag(holder);
            } else {
                holder = (ViewHolder) convertView.getTag();
            }

            holder.txtTitle.setText(data.get(position).get("article_title"));
            holder.txtAuthorName.setText(data.get(position).get("author_name"));
            holder.txtDescription.setText(data.get(position).get("article_text"));





            return convertView;
        }

        class ViewHolder {
            TextView txtTitle;
            TextView txtAuthorName;
            TextView txtDescription;
        }

    }

Upvotes: 0

luiscosta
luiscosta

Reputation: 855

Try this:

public View getView(int position, View convertView, ViewGroup parent) {

    LayoutInflater inflater = (LayoutInflater) context
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View rowView = inflater.inflate(layout, parent, false);

    //...

    return rowView;

}

Upvotes: 0

Related Questions