1

I am working on my first "professional" (ie, full-functional, bug-free, presentable) Android application, and I'm having some problems with Android layouts.

In particular, I have a gridView that I have inflated with a layout that has an ImageView, a TextView, and a hidden TextView (visibility set to "gone").

I have an "Image not found" image that is 115 x 115. The other images ("found") are similarly 115 x 115. They're all JPEGs.

The problem is that nothing's lining up. The text is constrained to under 17 characters. So I would think that the images being the same size and the text being the same size, the cells would be the same size and the grid would line up ... but noooo ;)

See here for how it looks now and here for how it looks with relative layout.

Both this and this suggest using a RelativeLayout.

The gridview:

     <?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="fill_parent">

    <GridView xmlns:android="http://schemas.android.com/apk/res/android"
              android:id="@+id/gridView"
              android:numColumns="auto_fit"
              android:gravity="top"
              android:layout_gravity="top"
              android:padding="10dp"
              android:verticalSpacing="10dp"
              android:horizontalSpacing="10dp"
              android:columnWidth="50dp"
              android:layout_width="fill_parent"
              android:layout_height="fill_parent" >
    </GridView>
</LinearLayout>

The cell:

    <RelativeLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/widget44"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:layout_gravity="top"
        android:gravity="top">
    <ImageView
            android:id="@+id/icon_image"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:gravity="top"
            android:layout_gravity="top">
    </ImageView>
    <TextView
            android:id="@+id/icon_text"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="TextView"
            android:gravity="center_horizontal"
            android:textColorHighlight="#656565">
    </TextView>
    <TextView
            android:id="@+id/full_text"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:visibility="gone"
            android:layout_gravity="top" >
    </TextView>
</RelativeLayout>

So ... I might have one thing wrong or several, to be sure. But I could use your help. Thanks.

EDIT: Someone suggested I post my adapter code, so here it is.

First, the gridview activity:

package com.buildingfive.sharealike;


import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.GridView;
import android.widget.ListAdapter;
import android.widget.TextView;
import com.buildingfive.R;

public class BrowseSearchProducts extends Activity {
    GridView gridView;
    Cursor cursor;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.browse_search);

        //get gridview data from db
        DBHelper db = new DBHelper(this);
        //this cursor is never really closed, everywhere I tried, GPF
        cursor = db.getReadableDatabase().rawQuery("SELECT _id, Title, Image FROM products;", null);
        cursor.moveToFirst();

        //populate gridview
        gridView = (GridView) findViewById(R.id.gridView);
        ListAdapter listAdapter = new ImageAdapter(this, cursor);
        ((ImageAdapter) listAdapter).setCount(cursor.getCount());
        gridView.setAdapter(listAdapter);

        gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
                TextView vText = (TextView) v.findViewById(R.id.full_text);
                String strCaption = ((TextView) vText).getText().toString();

                Intent intent = new Intent(BrowseSearchProducts.this, ShowDetails.class);
                intent.putExtra("search", strCaption);
                startActivity(intent);
            }
        });
    }

    @Override
    protected void onDestroy() {
        cursor.close();
        this.finish();
        super.onDestroy();
    }
}

Now the custom ImageAdapter:

package com.buildingfive.sharealike;

import android.content.Context;
import android.database.Cursor;
import android.graphics.BitmapFactory;
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 com.buildingfive.R;

public class ImageAdapter extends BaseAdapter {
    Context mContext;
    Cursor mCursor;
    int mCount;

    public static final int ACTIVITY_CREATE = 10;

    public ImageAdapter(Context c, Cursor cursor){
        mContext = c;
        mCursor = cursor;
    }

    public void setCount(int nCount) {
        this.mCount = nCount;
    }

    @Override
    public int getCount() {
        return mCount;
    }

    //also required
    public Object getItem(int position) {
        //should return the actual object at the specified position in our Adapter
        return mCursor.getString(1);
    }

    //required
    public long getItemId(int position) {
        return 0;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View vwIconPlusCaption;
        String strCaption = mCursor.getString(1);
        String strFull = strCaption;

        if (strCaption == "")
            return null;

        //The Beckham Experiment: Blah Blah Blah 2ndary Tagline
        if (strCaption.indexOf(":") > -1)
            strCaption = strCaption.split(":")[0].toString();
        else
            if (strCaption.length() >= 17)
                strCaption = strCaption.substring(0, 17);

        if(convertView == null){
            LayoutInflater li;
            li = LayoutInflater.from(mContext);

            //icon_plus_caption is loaded into a view
            vwIconPlusCaption = li.inflate(R.layout.icon_plus_caption, null);
            TextView tv = (TextView) vwIconPlusCaption.findViewById(R.id.icon_text);

            //the view's caption set here
            tv.setText(strCaption);
            TextView fullText = (TextView) vwIconPlusCaption.findViewById(R.id.full_text);
            //passes the full title in a hidden ("gone") textview
            fullText.setText(strFull);
            ImageView iv = (ImageView) vwIconPlusCaption.findViewById(R.id.icon_image);

            byte[] bb = mCursor.getBlob(2);
            if (bb == null) {
                //image not found
                iv.setImageResource(R.drawable.not_found);
            } else {
                iv.setImageBitmap(BitmapFactory.decodeByteArray(bb, 0, bb.length));
            }

            if (position + 1 < mCount)
                mCursor.moveToNext();
        }
        else
        {
            vwIconPlusCaption = convertView;
        }
        return vwIconPlusCaption;
    }
}

EDIT: SOLVED: SOLUTION IS AS FOLLOWS:

For some reason, the sizes differ when pulling all the images from SQL lite VS the "not found" image from android resources. See this link for more info.

The line I added was:

            iv.setImageBitmap(Bitmap.createScaledBitmap(bitmap, 115, 115, true));

... in order to force the size of the android drawable to 115 x 115.

Thanks for everyone who tried to pitch in.

Community
  • 1
  • 1
user426364
  • 160
  • 9
  • I tried your layout files (the only change being to make the cell a linearlayout) and it worked fine, so the issue is somewhere else, perhaps in your adapter or the images you are using. – Barak May 29 '12 at 12:23
  • Ok, Barak, I saved 'em as edits above. Thx. But how could they be in the images if everything's 115 x 115 JPEG? – user426364 May 29 '12 at 13:02
  • As I said, with icons I had here, and using your layout code, everything came out like it should. So the issue is either in your adapter or in the image. Right now I'd lean towards the image. I wouldn't be so certain about that image size... the two that are out of line in your image are the same icon, and both have extra space above and below. Can you add a third item with a different image (from any used previously) and see what happens? Maybe double check that pattern one too. – Barak May 29 '12 at 14:35
  • I figured it out. See my edit above. – user426364 May 29 '12 at 17:17
  • So I was right, it was an issue with the images. :) – Barak May 29 '12 at 17:53

0 Answers0