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.
Related
I am working on a application which require image and text group together in horizontal scroll bar.
I have tried few things but i am unable to get this, can anyone guide me with this guys.
Here is what i a have done,
main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<HorizontalScrollView
android:id="#+id/horizontalScrollView1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:fillViewport="true"
android:scrollbars="horizontal" >
<GridView
android:layout_height="wrap_content"
android:id="#+id/gridView1"
android:layout_width="wrap_content"
android:horizontalSpacing="10dp"
android:stretchMode="columnWidth"
android:scrollbars="horizontal"
android:verticalSpacing="10dp">
</GridView>
</HorizontalScrollView>
</LinearLayout>
gridview_row.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
android:id="#+id/relativeLayout1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
xmlns:android="http://schemas.android.com/apk/res/android"
android:background="#drawable/border"
android:padding="5dp">
<ImageView
android:layout_height="64dp"
android:id="#+id/imageView1"
android:layout_width="64dp"
android:src="#drawable/icon"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true">
</ImageView>
<TextView
android:text="TextView"
android:layout_height="wrap_content"
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_below="#+id/imageView1"
android:layout_marginTop="2dp"
android:layout_centerHorizontal="true"
android:textSize="18sp"></TextView>
</RelativeLayout>
GridviewExampleActivity.java
package com.paresh.gridviewexample;
import java.util.ArrayList;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.GridView;
public class GridViewExampleActivity extends Activity {
/** Called when the activity is first created. */
private GridviewAdapter mAdapter;
private ArrayList<String> listCountry;
private ArrayList<Integer> listFlag;
private GridView gridView;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
prepareList();
// prepared arraylist and passed it to the Adapter class
mAdapter = new GridviewAdapter(this,listCountry, listFlag);
// Set custom adapter to gridview
gridView = (GridView) findViewById(R.id.gridView1);
gridView.setAdapter(mAdapter);
// Implement On Item click listener
gridView.setOnItemClickListener(new OnItemClickListener()
{
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int position,
long arg3) {
Toast.makeText(GridViewExampleActivity.this, mAdapter.getItem(position), Toast.LENGTH_SHORT).show();
}
});
}
public void prepareList()
{
listCountry = new ArrayList<String>();
listCountry.add("india");
listCountry.add("Brazil");
listCountry.add("Canada");
listCountry.add("China");
listCountry.add("France");
listCountry.add("Germany");
listCountry.add("Iran");
listCountry.add("Italy");
listCountry.add("Japan");
listCountry.add("Korea");
listCountry.add("Mexico");
listCountry.add("Netherlands");
listCountry.add("Portugal");
listCountry.add("Russia");
listCountry.add("Saudi Arabia");
listCountry.add("Spain");
listCountry.add("Turkey");
listCountry.add("United Kingdom");
listCountry.add("United States");
listFlag = new ArrayList<Integer>();
listFlag.add(R.drawable.india);
listFlag.add(R.drawable.brazil);
listFlag.add(R.drawable.canada);
listFlag.add(R.drawable.china);
listFlag.add(R.drawable.france);
listFlag.add(R.drawable.germany);
listFlag.add(R.drawable.iran);
listFlag.add(R.drawable.italy);
listFlag.add(R.drawable.japan);
listFlag.add(R.drawable.korea);
listFlag.add(R.drawable.mexico);
listFlag.add(R.drawable.netherlands);
listFlag.add(R.drawable.portugal);
listFlag.add(R.drawable.russia);
listFlag.add(R.drawable.saudi_arabia);
listFlag.add(R.drawable.spain);
listFlag.add(R.drawable.turkey);
listFlag.add(R.drawable.united_kingdom);
listFlag.add(R.drawable.united_states);
}
}
GridviewAdapter.java
package com.paresh.gridviewexample;
import java.util.ArrayList;
import android.app.Activity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
public class GridviewAdapter extends BaseAdapter
{
private ArrayList<String> listCountry;
private ArrayList<Integer> listFlag;
private Activity activity;
public GridviewAdapter(Activity activity,ArrayList<String> listCountry, ArrayList<Integer> listFlag) {
super();
this.listCountry = listCountry;
this.listFlag = listFlag;
this.activity = activity;
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return listCountry.size();
}
#Override
public String getItem(int position) {
// TODO Auto-generated method stub
return listCountry.get(position);
}
#Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return 0;
}
public static class ViewHolder
{
public ImageView imgViewFlag;
public TextView txtViewTitle;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
ViewHolder view;
LayoutInflater inflator = activity.getLayoutInflater();
if(convertView==null)
{
view = new ViewHolder();
convertView = inflator.inflate(R.layout.gridview_row, null);
view.txtViewTitle = (TextView) convertView.findViewById(R.id.textView1);
view.imgViewFlag = (ImageView) convertView.findViewById(R.id.imageView1);
convertView.setTag(view);
}
else
{
view = (ViewHolder) convertView.getTag();
}
view.txtViewTitle.setText(listCountry.get(position));
view.imgViewFlag.setImageResource(listFlag.get(position));
return convertView;
}
}
My ouput should be
------------ ---------- ------------ ----
Image Image Image Image Image Image Image Image Image Image Image
Text Text Text Text Text Text Text Text Text Text Text
------------ ---------- ------------ --
Please Help me guys
Hi there just have a look at CustomArrayAdapter used for ListViews and Gridviews especially point 10 at this Tutoiral there you get to know how to customize your GridView/ListView (handled same way)
This might also help
If you have problems with the hotrizontal way, try this project: https://github.com/jess-anders/two-way-gridview
I am fairly new to android development and i'm creating a few simple applications for myself.
I have ran into a problem in relation to animations, in particular a flip animation on each individual cell of a gridview when that cell is clicked.
What my application does so far is retrieves the contacts from the phone and displays the contact photo and the name in a gridview using an array adapter.
What i want to happen is when the user clicks on the grid cell of a contact it will perform a flip animation and display the contacts phone number on the back.
When the user clicks on that cell again it will flip back to the previous view of the name and photo.
I have searched the internet and tried a few tutorials but none that have been of any great help, must of them infact confuse me, so if someone could help that would be great.
I'll post my current code below!
Thanks in advance.
This code is used to retrieve the information of the contacts!
package content;
import android.provider.MediaStore.Images;
public class ContactBean {
private String name;
private String phoneNo;
private String proPic;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPhoneNo() {
return phoneNo;
}
public void setPhoneNo(String phoneNo) {
this.phoneNo = phoneNo;
}
public String getProPic() {
return proPic;
}
public void setProPic(String proPic) {
this.proPic = proPic;
}
}
ViewContatcsActivity
package viewContacts;
import com.example.contactflipper.R;
import content.ContactBean;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.view.View;
import android.widget.AdapterView;
import android.widget.GridView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemClickListener;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class ViewContactsActivity extends Activity implements
OnItemClickListener {
private GridView listView;
private List<ContactBean> list = new ArrayList<ContactBean>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.menu_viewcon_grid);
listView = (GridView) findViewById(R.id.gridview);
listView.setOnItemClickListener(this);
String image_uri = "";
Bitmap bitmap = null;
Cursor phones = getContentResolver().query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null,
null, null);
while (phones.moveToNext()) {
String name = phones
.getString(phones
.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
String phoneNumber = phones
.getString(phones
.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
image_uri = phones
.getString(phones
.getColumnIndex(ContactsContract.CommonDataKinds.Phone.PHOTO_URI));
ContactBean objContact = new ContactBean();
objContact.setName(name);
objContact.setPhoneNo(phoneNumber);
list.add(objContact);
}
phones.close();
GridAdapter objAdapter = new GridAdapter(
ViewContactsActivity.this, R.layout.card_front, list);
listView.setAdapter(objAdapter);
if (null != list && list.size() != 0) {
Collections.sort(list, new Comparator<ContactBean>() {
#Override
public int compare(ContactBean lhs, ContactBean rhs) {
return lhs.getName().compareTo(rhs.getName());
}
});
AlertDialog alert = new AlertDialog.Builder(
ViewContactsActivity.this).create();
alert.setTitle("");
alert.setMessage(list.size() + " Contact Found!!!");
alert.setButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
alert.show();
} else {
showToast("No Contact Found!!!");
}
}
private void showToast(String msg) {
Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
}
#Override
public void onItemClick(AdapterView<?> listview, View v, int position,
long id) {
ContactBean bean = (ContactBean) listview.getItemAtPosition(position);
//implement something on the click of each listed item - bean
}
}
GridAdapter
package viewContacts;
import java.util.List;
import com.example.contactflipper.R;
import com.example.contactflipper.R.id;
import content.ContactBean;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.text.Html;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
public class GridAdapter extends ArrayAdapter<ContactBean> {
private Activity activity;
private List<ContactBean> items;
private int row;
private ContactBean objBean;
public GridAdapter(Activity act, int row, List<ContactBean> items) {
super(act, row, items);
this.activity = act;
this.row = row;
this.items = items;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
View view = convertView;
ViewHolder holder;
if (view == null) {
LayoutInflater inflater = (LayoutInflater) activity
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(row, null);
holder = new ViewHolder();
view.setTag(holder);
} else {
holder = (ViewHolder) view.getTag();
}
if ((items == null) || ((position + 1) > items.size()))
return view;
objBean = items.get(position);
holder.tvname = (TextView) view.findViewById(R.id.profileName);
//holder.tvPhoneNo = (TextView) view.findViewById(R.id.tvphone);
if (holder.tvname != null && null != objBean.getName()
&& objBean.getName().trim().length() > 0) {
holder.tvname.setText(Html.fromHtml(objBean.getName()));
}
if (holder.tvPhoneNo != null && null != objBean.getPhoneNo()
&& objBean.getPhoneNo().trim().length() > 0) {
holder.tvPhoneNo.setText(Html.fromHtml(objBean.getPhoneNo()));
}
if (holder.ivPic != null && null != objBean.getProPic()
&& objBean.getProPic().trim().length() > 0) {
holder.ivPic.setBackground((Drawable) Html.fromHtml(objBean.getProPic()));
}
return view;
}
public class ViewHolder {
public TextView tvname, tvPhoneNo;
public ImageView ivPic;
}
}
ViewContactsFragment
package viewContacts;
import com.example.contactflipper.R;
import com.example.contactflipper.R.id;
import com.example.contactflipper.R.layout;
import content.AppDetails;
import android.app.Activity;
import android.app.Fragment;
import android.content.res.Configuration;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.GridView;
public class VCGridFragment extends Fragment {
public static GridView mGridview;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
View view = inflater.inflate(R.layout.menu_viewcon_grid, container, false);
Log.d("Called", "on Create View");
return view;
}
//super.onCreateView(inflater, container, savedInstanceState);
#Override
public void onViewCreated(View view, Bundle savedInstanceState){
super.onViewCreated(view, savedInstanceState);
Log.d("Called", "created Grid");
mGridview = (GridView) view.findViewById(R.id.gridview);
Configuration config = getResources().getConfiguration();
if(AppDetails.isTablet){
if(config.orientation == Configuration.ORIENTATION_LANDSCAPE){
mGridview.setNumColumns(4);
}else{
mGridview.setNumColumns(3);
}
}else{
if(config.orientation == Configuration.ORIENTATION_LANDSCAPE){
mGridview.setNumColumns(3);
}else{
mGridview.setNumColumns(2);
}
}
/*
mGridview.setOnItemClickListener(new onItemClickLitener(){
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id){
onGridItemClick((GridView) parent, view, position, id);
}
});
}
public void onGridItemClick(GridView g, View v, int position, long id){
Activity activity = getActivity();
}
*/
}
}
GridView xml -
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/contact_grid"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:background="#ffffff"
android:scrollbars="none"
tools:context=".MainActivity" >
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:background="#drawable/gradient"
android:padding="10dp" >
<GridView
android:id="#+id/gridview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="50dp"
android:numColumns="2"
android:horizontalSpacing="8dp"
android:scrollbars="none"
android:verticalSpacing="8dp" >
</GridView>
<Button
android:id="#+id/backButton"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:layout_gravity="top|right"
android:background="#8043BFC7"
android:text="#string/edit_contacts"
android:textColor="#ffffff"
android:textStyle="bold" />
</FrameLayout>
</RelativeLayout>
FRONT OF CARD XML -
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="180dp"
android:layout_height="180dp"
android:orientation="vertical" >
<ImageView
android:id="#+id/profileThumb"
android:layout_width="match_parent"
android:layout_height="140dp"
></ImageView>
<TextView
android:id="#+id/profileName"
android:layout_width="match_parent"
android:layout_height="40dp"
android:layout_gravity="bottom"
android:background="#40000000"
android:textColor="#ffffff"
android:textSize="22sp">
</TextView>
</LinearLayout>
BACK OF CARD XML -
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="180dp"
android:layout_height="180dp"
android:orientation="vertical"
android:background="#a6c"
android:padding="10dp"
android:gravity="bottom"
>
<TextView
android:id="#+id/infoName"
style="?android:textAppearanceLarge"
android:textStyle="bold"
android:textColor="#fff"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="HCKDAHOIW"
></TextView>
<TextView
android:id="#+id/infoLocality"
style="?android:textAppearanceSmall"
android:textAllCaps="true"
android:textStyle="bold"
android:textColor="#80ffffff"
android:lineSpacingMultiplier="1.2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="convoy"
></TextView>
<TextView
android:id="#+id/infoEmail"
style="?android:textAppearanceSmall"
android:textColor="#80ffffff"
android:lineSpacingMultiplier="1.2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="fowfow#email.com"
></TextView>
<TextView
android:id="#+id/infoNumber"
style="?android:textAppearanceSmall"
android:textColor="#80ffffff"
android:lineSpacingMultiplier="1.2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="(086) 123 4567"
></TextView>
</LinearLayout>
I would go about it something like this.
Let's say this is the layout you're going to inflate in your gridview and it's named view_flipper_layout. Of course you'd have to add all your textview components etc. to either the front or back linearlayout.
<?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" >
<ViewFlipper
android:id="#+id/my_view_flipper"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout
android:id="#+id/front"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="#+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Large Text"
android:textAppearance="?android:attr/textAppearanceLarge" />
</LinearLayout>
<LinearLayout
android:id="#+id/back"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ImageView
android:id="#+id/picture"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
</ViewFlipper>
</LinearLayout>
Now let's say this is the adapter
public GridAdapter(Activity act, int row, List<ContactBean> items) {
super(act, row, items);
this.activity = act;
this.row = row;
this.items = items;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
View view = convertView;
ViewHolder holder;
if (view == null) {
LayoutInflater inflater = (LayoutInflater) activity
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
//here is where you inflate your layout containing your viewflipper
view = inflater.inflate(R.layout.view_flipper_layout, null);
} else {
holder = (ViewHolder) view.getTag();
}
//reference the viewFlipper
ViewFlipper flipper = (viewFlipper) holder.findViewById(R.id.my_view_flipper);
//your front layout should be set to displayed be default
//now you can get get references to your textview or ImageViews contained within the layout
TextView name = (TextView) holder.findViewById(R.id.name);
name.setText("your text");
ImageView picture = (ImageView) holder.findViewById(R.id.picture);
//now you set your onclick and pass it the current viewflipper to control the displayed child
flipper.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View click) {
flipViewFlipper(flipper);
}
});
return view;
}
private void flipViewFlipper(ViewFlipper flipper){
if(flipper.getDisplayedChild() == 0){
flipper.setDisplayedChild(1);
}
else{
flipper.setDisplayeChild(0);
}
}
}
I'm typing this from my head, so just use it as a guide if you attempt to go this way.
Like the title says, my setOnItemClickListener isn't working. I looked through everything I've seen so far on SO and couldn't find my error.
This is the code:
This is the problematic class. It isn't the main class, but is called from an intent:
package...;
import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListAdapter;
import android.widget.ListView;
public class GroupActivity extends Activity {
String group_id = "";
Context context;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_group);
context = this;
Intent intent = getIntent();
group_id = intent.getStringExtra("group_id");
Log.i("bla", "Launched GroupActivity for group_id " + group_id);
final SubAdapter adapter = new SubAdapter(this, group_id);
ListView lv = (ListView) findViewById(R.id.listView1);
lv.setClickable(true);
lv.setAdapter(adapter);
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> av, View v, int idx, long lidx) {
Log.i("print here", "blaa " + idx);
}
});
}
#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;
}
}
This is the SubAdapter class:
package...;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.text.format.DateUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
public class SubAdapter extends BaseAdapter {
private static final int thumb_width = 128;
private static final int thumb_hight = 128;
private static Bitmap default_thumb = null;
private static LayoutInflater inflater = null;
private final String group_id_;
private final Activity activity;
private final SubAdapter t = this;
// used to keep selected position in ListView
private int selectedPos = -1; // init value for not-selected
public SubAdapter(Activity a, final String group_id) {
Drawable d = a.getResources().getDrawable(R.drawable.ic_contact_picture);
default_thumb = ((BitmapDrawable) d).getBitmap();
activity = a;
group_id_ = group_id;
inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public View getView(int idx, View convertView, ViewGroup parent) {
Log.i("bla2", "getting view with index " + idx);
View vi = convertView;
if (convertView == null) {
vi = inflater.inflate(R.layout.sub_list_item, null);
vi.setClickable(true);
}
TextView tv1 = (TextView)vi.findViewById(R.id.textView1);
TextView tv2 = (TextView)vi.findViewById(R.id.textView2);
ImageView img = (ImageView)vi.findViewById(R.id.imageView1);
tv1.setText("first name" + " " + "last name");
tv2.setText("some date");
// put thumbnail
Bitmap thumb = default_thumb;
img.setImageBitmap(thumb);
Log.i("bla3", "index is " + idx + "selected index is " + selectedPos);
if(selectedPos == idx){
Log.i("bla4", "inside if");
}
return vi;
}
public void setSelectedPosition(int pos){
selectedPos = pos;
// inform the view of this change
notifyDataSetChanged();
}
#Override
public void notifyDataSetChanged() {
super.notifyDataSetChanged();
}
}
This is the activity_group xml:
<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=".GroupActivity" >
<ListView
android:id="#+id/listView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="true"
android:focusableInTouchMode="false"
android:focusable="false" >
</ListView>
</RelativeLayout>
This is the sub_list_item xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="true"
android:focusable="false"
android:focusableInTouchMode="false">
<ImageView
android:id="#+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_margin="6dp"
android:src="#drawable/ic_launcher" />
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_margin="6dp"
android:layout_toLeftOf="#+id/toggleButton1"
android:layout_toRightOf="#+id/imageView1"
android:text="some text"
android:textAppearance="?android:attr/textAppearance" />
<TextView
android:id="#+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/textView1"
android:layout_below="#+id/textView1"
android:layout_toLeftOf="#+id/toggleButton1"
android:text="more text"
android:textAppearance="?android:attr/textAppearance" />
<ToggleButton
android:id="#+id/toggleButton1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_margin="6dp"
android:text="present" />
</RelativeLayout>
Apart from the click listener, everything else seems to work. The SubAdapter opens properly and the list is populated.
Basically what I'm looking for is to get the message "Log.i("print here", "blaa " + idx);" to print - it is the log from the ListView's setOnItemClickListener (look above)
Please let me know if there is any other relevant code missing
Thanks!!!
In your GroupActivity class please add the following code before findViewById method:
now you get the view same and change your code
ListView lv = (ListView) findViewById(R.id.listView1);
to
final View v = inflater.inflate(R.layout.rescuer_no_dialog, null);
ListView lv = (ListView)v.findViewById(R.id.listView1);
You should probably remove the call to
vi.setClickable(true); in your SubAdapter class, because your convertView will consume the click before you onItemClick listener.
Change this
ListView lv = (ListView) findViewById(R.id.listView1);
to
lv = getListView()
Extend ListActivity and declare lv outside methods.
Well, I am not sure what is up. I've been through many SO "answers" without any results. I have a custom adapter running on my listview. I want to be able to click on the list item to "see more" but I cannot even get the click to register.
Here is my activity:
import java.util.ArrayList;
import java.util.List;
import android.app.ProgressDialog;
import android.content.Context;
import android.os.Bundle;
import android.text.method.LinkMovementMethod;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
import com.actionbarsherlock.app.SherlockActivity;
import com.androidquery.AQuery;
import com.androidquery.callback.AjaxStatus;
import com.androidquery.util.XmlDom;
public class MainActivity extends SherlockActivity {
private AQuery aq;
private ProgressDialog dialog;
private static final String TAG = "INCIWEB";
private ListView lv;
protected Object IncidentAdapter;
EditText inputSearch;
String url;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
setContentView(R.layout.activity_main);
getSupportActionBar().setSubtitle("Incidents across the USA");
aq = new AQuery(this);
dialog = new ProgressDialog(this);
dialog.setCancelable(true);
dialog.setInverseBackgroundForced(false);
dialog.setCanceledOnTouchOutside(true);
dialog.setMessage("Fetching Latest...");
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(
this, R.array.USStates, android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
Spinner s = (Spinner) findViewById(R.id.stateSpinner);
s.setAdapter(adapter);
s.setPrompt("Select a location...");
final String USStates = s.getSelectedItem().toString();
Log.e("STATE", USStates);
s.setOnItemSelectedListener(new OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parentView,
View selectedItemView, int position, long id) {
try {
getFeed(position);
} catch (Exception e) {
Log.e(TAG, e.getMessage());
}
}
#Override
public void onNothingSelected(AdapterView<?> parentView) {
}
});
}
public void getFeed(int num) {
if (num == 0) {
// latest updates - front page
url = "http://inciweb.org/feeds/rss/incidents/";
} else {
// states
url = "http://inciweb.org/feeds/rss/incidents/state/" + num + "/";
}
Log.e("URL", url);
long expire = -1;
aq.progress(dialog).ajax(url, XmlDom.class, expire, this,
"getFeedCallback");
}
public void getFeedCallback(String url, XmlDom xml, AjaxStatus status) {
List<XmlDom> entries = xml.tags("item");
List<Incidents> incidents = new ArrayList<Incidents>();
for (XmlDom entry : entries) {
incidents.add(new Incidents(entry.text("title"),
entry.text("link"), entry.text("description"), entry
.text("published"), entry.text("geo:lat"), entry
.text("geo:long"), entry.text("georss:point")));
}
lv = (ListView) findViewById(R.id.list);
lv.setTextFilterEnabled(true);
lv.setAdapter(new IncidentAdapter(this,
android.R.layout.simple_list_item_1, incidents));
lv.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View view,
int position, long id) {
Toast.makeText(MainActivity.this, id + "' was clicked.",
Toast.LENGTH_LONG).show();
}
});
}
private class IncidentAdapter extends ArrayAdapter<Incidents> {
private List<Incidents> items;
public IncidentAdapter(Context context, int textViewResourceId,
List<Incidents> items) {
super(context, textViewResourceId, items);
this.items = items;
}
// Create a title and detail
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.incidents_item, null);
}
Incidents o = items.get(position);
if (o != null) {
TextView title = (TextView) v.findViewById(R.id.title);
TextView published = (TextView) v.findViewById(R.id.published);
TextView link = (TextView) v.findViewById(R.id.link);
link.setMovementMethod(LinkMovementMethod.getInstance());
TextView description = (TextView) v
.findViewById(R.id.description);
TextView geoLat = (TextView) v.findViewById(R.id.geoLat);
TextView geoLon = (TextView) v.findViewById(R.id.geoLon);
TextView geoLatLon = (TextView) v.findViewById(R.id.geoLatLon);
if (title != null) {
title.setText(o.getTitle());
}
if (published != null) {
published.setText(o.getPublished());
}
if (link != null) {
link.setText(o.getLink());
}
if (description != null) {
description.setText(o.getDescription());
}
if (geoLat != null) {
geoLat.setText(o.getGeoLat());
}
if (geoLon != null) {
geoLon.setText(o.getGeoLon());
}
if (geoLatLon != null) {
geoLatLon.setText(o.getGeoLatLon());
}
}
return v;
}
}
}
What am I missing?
edit:
Here is my XML files...
activity_main.xml
<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=".MainActivity" >
<Spinner
android:id="#+id/stateSpinner"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/inputSearch" />
<ListView
android:id="#+id/list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_below="#+id/stateSpinner" />
</RelativeLayout>
incident_items.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" >
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:id="#+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:textSize="20sp" />
<TextView
android:id="#+id/published"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical" />
<TextView
android:id="#+id/link"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical" />
<TextView
android:id="#+id/description"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical" />
<TextView
android:id="#+id/geoLat"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical" />
<TextView
android:id="#+id/geoLon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical" />
<TextView
android:id="#+id/geoLatLon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical" />
</LinearLayout>
</LinearLayout>
EDIT:
What I'd like to do is show the Title from the XML, then show the other XML fields onClick of the XML title from the listview...
Maybe your custom Views in ListView has clickable items and consume click event?
Make sure your ListView has the focus and there are no other clickable items that could steal the click events.
Well I cannot be 100% sure why it is working now, however, I think it has to do with going back through my XML and making sure nothing was missing or even a bit off according to Eclipse.
Thanks for all the comments.
For future folks: CHECK YOUR XML.
I am relatively new to android and I really need help with this one. I am trying to write some code that will display the pictures on the sd card using a GridView, but so far when I run the application only the textview at the top is shown. I would like to know if there is a serious flaw in the logic of my code in the Main Activity code, Image Adapter class code or both. This is my code:
package com.newtestforsdcarddisplay;
import android.app.Activity;
import android.os.Bundle;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.view.View;
import android.widget.GridView;
import android.widget.AdapterView;
import android.widget.Toast;
import android.provider.MediaStore;
import android.provider.MediaStore.Images.Thumbnails;
import android.net.Uri;
import android.widget.AdapterView.OnItemClickListener;
public class MainActivity extends Activity {
public Cursor myImageCursor;
public int columnNumber;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
String[] imageIDs = new String[]{Thumbnails._ID};
Uri myImagesSource = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
myImageCursor = managedQuery(myImagesSource,
imageIDs, null, null, MediaStore.Images.Thumbnails._ID);
columnNumber = myImageCursor.getColumnIndexOrThrow(MediaStore.Images.Media._ID);
GridView PhoneImageView = (GridView)findViewById(R.id.sdcard);
PhoneImageView.setAdapter(new ImageAdapter(this));
PhoneImageView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v,
int position, long id) {
String[] data = { MediaStore.Images.Media.DATA };
Cursor viewImageCursor = managedQuery(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI, data,
null, null, MediaStore.Images.Thumbnails._ID );
int imageColumnIndex = viewImageCursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
viewImageCursor.moveToPosition(position);
viewImageCursor.moveToFirst();
String filepath = viewImageCursor.getString(imageColumnIndex);
Toast.makeText(MainActivity.this, filepath, Toast.LENGTH_LONG).show();
Bitmap yourSelectedImage = BitmapFactory.decodeFile(filepath);
}
});
}
}
package com.newtestforsdcarddisplay;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;
import android.net.Uri;
import android.provider.MediaStore;
public class ImageAdapter extends BaseAdapter{
final MainActivity pca = new MainActivity();
private Context context;
public ImageAdapter(Context localContext) {
// context = localContext;
}
public int getCount() {
// return pca.myImageCursor.getCount();
return 0;
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
ImageView picturesView;
if (convertView == null) {
picturesView = new ImageView(context);
// Move cursor to current position
pca.myImageCursor.moveToPosition(position);
// Get the current value for the requested column
int imageID = pca.myImageCursor.getInt(pca.columnNumber);
// Set the content of the image based on the provided URI
picturesView.setImageURI(Uri.withAppendedPath(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "" + imageID));
picturesView.setScaleType(ImageView.ScaleType.FIT_CENTER);
picturesView.setPadding(8, 8, 8, 8);
picturesView.setLayoutParams(new GridView.LayoutParams(100, 100));
}
else {
picturesView = (ImageView)convertView;
}
return picturesView;
}
}
package com.newtestforsdcarddisplay;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;
import android.net.Uri;
import android.provider.MediaStore;
public class ImageAdapter extends BaseAdapter{
final MainActivity pca = new MainActivity();
private Context context;
public ImageAdapter(Context localContext) {
// context = localContext;
}
public int getCount() {
// return pca.myImageCursor.getCount();
return 0;
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
ImageView picturesView;
if (convertView == null) {
picturesView = new ImageView(context);
// Move cursor to current position
pca.myImageCursor.moveToPosition(position);
// Get the current value for the requested column
int imageID = pca.myImageCursor.getInt(pca.columnNumber);
// Set the content of the image based on the provided URI
picturesView.setImageURI(Uri.withAppendedPath(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "" + imageID));
picturesView.setScaleType(ImageView.ScaleType.FIT_CENTER);
picturesView.setPadding(8, 8, 8, 8);
picturesView.setLayoutParams(new GridView.LayoutParams(100, 100));
}
else {
picturesView = (ImageView)convertView;
}
return picturesView;
}
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/hello"
/>
<GridView
android:id="#+id/sdcard"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="10dp"
android:verticalSpacing="10dp"
android:horizontalSpacing="10dp"
android:numColumns="auto_fit"
android:columnWidth="90dp"
android:stretchMode="columnWidth"
android:gravity="center"
/>
</LinearLayout>
Could somebody help me please???? As I said before, I am fairly new to android and I have been struggling with this for a really long time. Any help would VERY MUCH appreciated.
Do you still need help with this question?
What I would do is create a "root" layout like this
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<include layout="#layout/my_header"/>
<include layout="#layout/my_grid"/>
</LinearLayout>
In the my_header.xml, just set your textview in a linear layout.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android">
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/hello"
/>
</LinearLayout>
Then in your my_grid.xml, setup your gridview
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android">
<GridView
android:id="#+id/sdcard"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="10dp"
android:verticalSpacing="10dp"
android:horizontalSpacing="10dp"
android:numColumns="auto_fit"
android:columnWidth="90dp"
android:stretchMode="columnWidth"
android:gravity="center"
/>
</LinearLayout>
Good luck
your getCount() is returning 0. i think you should return myImageCursor.getCount()
you can change constructor to
ImageAdapter(Context ctx,Cursor cr)
{
this.context=ctx;
this.cursor=cr;
}
and then use cr.getCount() in adapter's getCount()