I have an app where i can pick images from the sdcard. Once images have been picked, say from the photos folder, you can view the selected images in a ListView.
The selected images are passed to the listview using an Adapter which takes an array of paths to each image.
It all works fine, but how do make the image fit to the width of the listview row?
thanks in advance.
public class QueuedImagesActivity extends Activity {
private static final String TAG = QueuedImagesActivity.class.getSimpleName();
private ImageAdapter adapter;
private ListView imageList;
private ApplicationObj appObj;
private Intent[] uniquePhotoChunks;
private String path;
private ArrayList<String> imagePaths = new ArrayList<String>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.image_listview);
appObj = (ApplicationObj) getApplication();
// Get the queued chunks
try {
boolean includeChunksCurrentlyBeingProcessed = true;
boolean returnUniqueUris = true;
uniquePhotoChunks = appObj.getQueuedChunks(includeChunksCurrentlyBeingProcessed, returnUniqueUris);
Log.d(TAG, "There are " + uniquePhotoChunks.length + " photo paths sent back from getQueuedChunks");
//get the URI out from the Intent with getDataString() and store in Array that the adapter will use
for(int i = 0; i < uniquePhotoChunks.length; i++){
path = uniquePhotoChunks[i].getDataString();
imagePaths.add(path);
Log.d(TAG, "path in QueuedImagesActivity = " + path);
}
//pass the array to the adapter
imageList = (ListView) findViewById(R.id.listView1);
adapter = new ImageAdapter(getBaseContext(), imagePaths);
imageList.setAdapter(adapter);
}
catch (Exception e) {
Log.e(TAG, "There was a problem showing the queued images", e);
Toast.makeText(this, "There was a problem showing the queued images", Toast.LENGTH_LONG).show();
Intent intent = new Intent(this, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
}
}//end of onCreate
}
.
<?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" >
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:text="List of Images"
android:textAppearance="?android:attr/textAppearanceMedium" />
<ListView
android:id="#+id/listView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/textView1"
android:layout_centerHorizontal="true" >
</ListView>
</RelativeLayout>
.
public class ImageAdapter extends BaseAdapter {
private static final String TAG = ImageAdapter.class.getSimpleName();
static class RowItemHolder{
ImageView imageView;
}
private Context context;
private ArrayList<String> imagePaths= new ArrayList<String>();
public ImageAdapter(Context baseContext, ArrayList<String> imagePaths) {
this.context= baseContext;
this.imagePaths= imagePaths;
}
#Override
public int getCount() {
return imagePaths.size();
}
#Override
public Object getItem(int position) {
return null;
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view;
view= convertView;
RowItemHolder holder = null;
if(view== null){
LayoutInflater in =(LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = in.inflate(R.layout.image_view, parent, false);
holder= new RowItemHolder();
holder.imageView=(ImageView) view.findViewById(R.id.imageView1);
view.setTag(holder);
} else{
holder = (RowItemHolder) view.getTag();
}
Log.e(TAG, "imagePaths.get(position) = " + imagePaths.get(position));
holder.imageView.setImageURI(Uri.parse(imagePaths.get(position)));
return view;
}
}
[edit1]
<?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" >
<ImageView
android:id="#+id/imageView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="#drawable/ic_launcher" />
</RelativeLayout>
Try to put the property android:scaleType="fitXY" in your ImageView like:
<ImageView
android:id="#+id/imageView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="#drawable/ic_launcher"
android:scaleType="fitXY" />
Hope this helps.
Set layout_width of image view in your R.Layout. image_view to match_parent.
An ImageView will only stretch images to fill the view bounds when they are set as the background. Images set as the src will maintain their original size or be shrunk to fit the view.
So you will need to get the drawable first and then call holder.imageView.setBackground(yourImageDrawable)
You can retrieve the drawable from a URI following something like this:
Retrieve drawable resource from Uri
Thus it should end up looking something like the code below
Uri uri = Uri.parse(imagePaths.get(position));
Drawable drawable;
try {
InputStream inputStream = context.getContentResolver().openInputStream(uri);
drawable = Drawable.createFromStream(inputStream, uri.toString() );
} catch (FileNotFoundException e) {
drawable = context.getResources().getDrawable(R.drawable.default_image);
}
holder.imageView.setBackgroundDrawable(drawable);
Related
I have a grid of images that were taken from a custom camera activity.
On other activity I load the images into a grid.
I have a method that turn on & off a checkbox on each Image.
While trying to move through all the images, I'm getting some strange behavior:
GridView.getCount() returns the correct number of images in the GridView, but GridView.getChildAt() method returned only part of the images.
so, when I try to do so, I get a null Exception.
The GridView Adapter:
public class PhotoGalleryAdapter extends ArrayAdapter {
// Declare variables
private Activity adapterActivity;
private int layoutResourceId;
private ArrayList gridItemsArray;
private static LayoutInflater inflater = null;
public PhotoGalleryAdapter(Activity a, int layoutResourceId, ArrayList fGridItemArray) {
super(a, layoutResourceId, fGridItemArray);
this.layoutResourceId = layoutResourceId;
this.adapterActivity = a;
this.gridItemsArray = fGridItemArray;
}
public int getCount() {
return gridItemsArray.size();
}
public Object getItem(int position) {
return gridItemsArray.get(position);
}
public long getItemId(int position) {
return position;
}
public View getView(final int position, View convertView, ViewGroup parent) {
HolderViewRow holderRow = null;
View rowView = (View) convertView;
if (rowView == null){
LayoutInflater inflater = adapterActivity.getLayoutInflater();
rowView = inflater.inflate(layoutResourceId, parent, false);
holderRow = new HolderViewRow();
holderRow.imageFileBMP = (ImageView) rowView.findViewById(R.id.imageObject);
holderRow.checkBox = (CheckBox) rowView.findViewById(R.id.itemCheckBox);
holderRow.checkBoxImage = (ImageView) rowView.findViewById(R.id.itemImageCheckBox);
rowView.setTag(holderRow);
}
else
{
holderRow = (HolderViewRow) rowView.getTag();
}
PhotoGalleryItem item = (PhotoGalleryItem) gridItemsArray.get(position);
// Set the decoded bitmap iitemnto ImageView
holderRow.imageFileBMP.setImageBitmap(item.getImageBMP());
holderRow.imageFilePath = item.getImagePath();
return rowView;
}
static class HolderViewRow {
ImageView imageFileBMP;
String imageFilePath;
CheckBox checkBox;
ImageView checkBoxImage;
}
}
public class PhotoGalleryItem {
private Bitmap imageBMP;
private String imagePath;
private CheckBox checkBox;
private ImageView checkBoxImage;
public PhotoGalleryItem(Bitmap imageBMP, String imagePath) {
super();
this.imageBMP = imageBMP;
this.imagePath = imagePath;
}
public Bitmap getImageBMP() {
return imageBMP;
}
public void setImageBMP(Bitmap imageBMP) {
this.imageBMP = imageBMP;
}
public String getImagePath() {
return imagePath;
}
public void setImagePath(String imagePath) {
this.imagePath = imagePath;
}
}
The Grid Activity:
private void RenderGridAndSetImages() {
// Locate the GridView in gridView_PhotoDisplay.xml
gridView = (GridView) findViewById(R.id.gridView_PhotoDisplay);
// Pass String arrays to Adapter Class
imageAdapter = new PhotoGalleryAdapter(this, R.layout.gridview_photo_item, GridItemArrayList);
gridView.setAdapter(imageAdapter);
}
And the function that has the problem:
public void SetVisibilityCheckBox_OnGrid (boolean checkBoxVisibility) {
// Handle item selection On GRIDVIEW ImageItem
final int size = gridView.getCount();
try {
ImageView imageCB;
int cbVisibility;
if (checkBoxVisibility)
cbVisibility = View.VISIBLE;
else
cbVisibility = View.INVISIBLE;
for(int i = 0; i < size; i++) {
View viewItem = (View) gridView.getChildAt(i);
if (viewItem != null) {
imageCB = (ImageView) viewItem.findViewById(R.id.itemImageCheckBox);
imageCB.setVisibility(cbVisibility);
}
}
}
catch (Exception ex) {
// Error occurred while SetSelectCheckBoxOnGrid
Log.e(PACKAGE_NAME, ACTIVITY_NAME + ".SetVisibilityCheckBox_OnGrid\n" + ex.getMessage());
}
}
The GridView Layout:
<RelativeLayout
android:id="#+id/layout_Holder"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:background="#color/activityBackground"
tools:context="com.mountain.saymera.PhotoGalleryActivity">
<!-- Image view: layout_GridView -->
<RelativeLayout
android:id="#+id/layout_PhotoGridDisplay"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:orientation="horizontal"
android:background="#color/activityBackground"
android:padding="1dp">
<GridView
android:id="#+id/gridView_PhotoDisplay"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:columnWidth="100dp"
android:drawSelectorOnTop="true"
android:numColumns="auto_fit"
android:verticalSpacing="1dp"
android:horizontalSpacing="1dp"
android:stretchMode="columnWidth"
android:gravity="center"
android:focusable="true"
android:clickable="true"/>
<TextView
android:id="#+id/textView_NoImages"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/gallery_no_images"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"
android:background="#00000000"
android:textColor="#color/MenuButtonTint"
android:textStyle="bold" />
</RelativeLayout>
</RelativeLayout>
The GridView Item Layout:
<RelativeLayout
android:id="#+id/layout_Holder"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:background="#drawable/single_photo_frame_on_grid">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:orientation="vertical"
android:background="#color/Grid_ItemFrame"
android:padding="0.3dp">
<com.mountain.saymera.SquareImageView
android:id="#+id/imageObject"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:adjustViewBounds="true"
android:scaleType="centerCrop"/>
</LinearLayout>
<CheckBox
android:id="#+id/itemCheckBox"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"
android:visibility="invisible"
android:tint="#color/Grid_ItemCheckbox"/>
<ImageView
android:id="#+id/itemImageCheckBox"
android:layout_width="25dp"
android:layout_height="25dp"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"
android:visibility="invisible"
android:background="#00000000"
android:src="#mipmap/ic_crop_square_black_24dp"
android:tint="#color/MenuCheckboxTint"/>
</RelativeLayout>
Need some help, Thanks
I have faced the same issue with programatically added ImageViews in a LinearLayout. Unfortunately, this method seems to be buggy at the moment, so I had to help myself by finding an alternative.
As a workaround, I saved the references of my ImageViews in a List and worked with them.
I have a custom listview. when te listview is called i want it to load all the profiles from my database, this works. but i also want to check the status of the profile and depending of the result i want to show a certain icon next to it. but i cant seem to figure out how to get this done properly.. this is what i have so far:
profiles_list.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:background="#color/colorAccent">
<ListView
android:id="#+id/listView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="10dp"
android:layout_marginBottom="10dp"
android:layout_above="#+id/menuBtn"
android:background="#2cffffff">
</ListView>
<RelativeLayout/>
list_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TableRow>
<ImageView
android:id="#+id/statusIcon"
android:layout_width="50dp"
android:layout_height="50dp"/>
<TextView
android:id="#+id/profile"
android:layout_width="wrap_content"
android:layout_height="50dp"
android:layout_marginLeft="10dp"/>
</TableRow>
</TableLayout>
MainActivity.class
public class ProfilesList extends CredenceOneActivity implements AdapterView.OnItemClickListener {
static final int STATUS_SUCCES =1;
static final int STATUS_WARNING =2;
static final int STATUS_ERROR =3;
private ListView list;
private ArrayAdapter<String> adapter;
private ArrayList<String> arrayList;
private DB_Handler db;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState == null) {
setContentView(R.layout.profiles_list);
}
list = (ListView) findViewById(R.id.listView);
arrayList = new ArrayList<String>();
try {
db = new DB_Handler(this);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
adapter = new ArrayAdapter<String>(getApplicationContext(), android.R.layout.simple_spinner_item, arrayList);
// Here, you set the data in your ListView
list.setAdapter(adapter);
list.setOnItemClickListener(this);
loadRegisteredProfiles();
}
public void loadRegisteredProfiles() {
List<DB_Profiles> storedProfiles = db.getAllProfiles();
for (DB_Profiles profile : storedProfiles) {
String name= profile.getNAME();
arrayList.add(name);
adapter.notifyDataSetChanged();
}
i want to do something like this for each profile that is loaded in the listview:
DB_Profiles profile;
if (profile.getStatus==STATUS_SUCCES{
statusIcon.setImageResource(R.drawable.succes);}
else{profile.getStatus==STATUS_ERROR{
statusIcon.setImageResource(R.drawable.error);}}
}
any advice would be greatly appreciated!
In the getView() of your Custom Adapter write the below piece of code.
ViewHolder holder;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.rowLayout, null);
holder = new ViewHolder();
holder.imagView = (ImageView) convertView.findViewById(R.id.img);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
if (profile.getStatus==STATUS_SUCCES)
{
holder.imagView.setImageResource(R.drawable.succes);
}
else if(profile.getStatus==STATUS_ERROR)
{
holder.imagView.setImageResource(R.drawable.error);
}
return convertView;
And declare static inner class in your custom adapter, like this
static class ViewHolder {
ImageView img;
}
In the getView() of the listview's adapter, you can use the setImageResource() of the imageView, in your list_item layout.
I know there are a lot of this kind of questions, but here is my problem.
I have a gallery with images and when I click, there is an ImageView to display the selected image in the gallery.
I also have a TextView witch displays a message.
When I click an image in the gallery, my ImageView gets the image and the TextTiew doesnt update its data.
I tried to put the code in a try/catch block and it doesn't throw any exception.
In my Log, the TextView has the exact text I have provided.
I tried using a new thread, but the result is the same: the TextView doesn't update, but my ImageView does.
I tried using runOnUiThread (as far as I know it's the same as a Thread), but still nothing.
I also changed from TextView to EditText, but I have the same problem.
Everyone says: "use a thread" - I did and it didn't work.
I ran out of ideas...
public class VODInterface extends Activity {
public static String[] values;
private static int itemPosition;
public static Activity thisActivity;
public Gallery gallery;
public ListView listView;
public LinearLayout MovieView;
public ImageView imgview;
public boolean submenus=false;
public boolean listviewVisibility = true;
private Handler handler = new Handler() ;
private SharedPreferences ep;
public ArrayList<VODObject> vod;
private ArrayList<Bitmap> tempimg;
private static int MovieSetNumber = 1;
public static int VODIndexPosition = 0;
public VODInterface(){
}
public void onDestroy(){
MainActivity.inChild=false;
super.onDestroy();
}
public void onCreate(Bundle bundle){
super.onCreate(bundle);
this.setContentView(R.layout.listview2);
ep = getSharedPreferences("Settings", 0);
listView = (ListView) this.findViewById(R.id.listView1);
MovieView = (LinearLayout) this.findViewById(R.id.movieView);
imgview = (ImageView)this.findViewById(R.id.imageView2);
// Defined Array values to show in ListView
values = new String[] { "A..Z",
"Category",
"Most Rated",
"Most Watched",
"Recently"
};
//this shows whitch movie should me load images
//we show always only 10 movies
MovieSetNumber = 1;
// Define a new Adapter
// First parameter - Context
// Second parameter - Layout for the row
// Third parameter - ID of the TextView to which the data is written
// Forth - the Array of data
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, android.R.id.text1, values);
// Assign adapter to ListView
listView.setAdapter(adapter);
// ListView Item Click Listener
listView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// ListView Clicked item index
itemPosition = position;
handler.post(goDeep);
}
});
}
private Runnable goDeep = new Runnable(){
public void run(){
new goDeep().execute("");
}
};
class goDeep extends AsyncTask<String, String, String>{
ProgressDialog mProgressDialog = new ProgressDialog(VODInterface.this);
String result="";
boolean failLoadVOD=false;
protected void onPreExecute(){
mProgressDialog.setMessage(getString(R.string.downloading));
mProgressDialog.setIndeterminate(true);
mProgressDialog.setCancelable(false);
mProgressDialog.show();
}
#Override
protected String doInBackground(String... arg0) {
// TODO Auto-generated method stub
//START check if servers are Ok
if(!Server.isOnline()){
Server.getAvailableServer();
Log.i("good", "");
}
if(!Server.isOnline()){
Log.i("WEW", "SERVERS are off");
return null;
}
//END check if servers are Ok
//START synchronize local database with online database
try{
if(ep.contains("downloaded")){
Log.i("localDatabase", "is full");
}
else{
Editor ed = ep.edit();
ed.putString("downloaded", "");
ed.commit();
//load data from database
if(!MainActivity.web.parseVODAndVODCategories()){
failLoadVOD=true;
}
}
}
catch(NullPointerException ee)
{
//lets go get datas from Tibodatabase
Editor ed = ep.edit();
ed.putString("downloaded", "");
ed.commit();
if(!MainActivity.web.parseVODAndVODCategories()){
failLoadVOD=true;
}
}
//END synchronize local database with online database
//START handle menus
if(!submenus) //MainMenu
{
if(itemPosition == 1){
//get all movies ordered by name
List<String> val = MainActivity.voddb.selectAllCategories();
values = new String[val.size()+1];
values[0] ="[...]";
for(int i=0;i<val.size();i++){
values[i+1] = val.get(i);
}
listviewVisibility = true;
}
else{
//show movies
listviewVisibility = false;
}
submenus = true;
}
else{
if(itemPosition == 0){
values = new String[] { "A..Z",
"Category",
"Most Rated",
"Most Watched",
"Recently"
};
submenus = false;
listviewVisibility = true;
}
else{
listviewVisibility = false;
}
}
//END handle menu
if(!listviewVisibility){
getData();
for(int i=0;i<vod.size();i++){
if(!FileExciste(vod.get(i).Icon)){
try{
Bitmap bmp ;
URL newurl = new URL(vod.get(i).Icon);
bmp = BitmapFactory.decodeStream(newurl.openConnection() .getInputStream());
saveImageToSD(bmp,vod.get(i).Icon);
Log.i(i+"", "done");
}
catch(Exception e){
Log.i("exciste", "exciste");
}
}
else{
Log.i(i+"", "exciste");
}
}
}
runOnUiThread(new Runnable() {
#Override
public void run() {
if(!listviewVisibility){
listView.setVisibility(View.GONE);
MovieView.setVisibility(View.VISIBLE);
populateMovieView();
}
else{
ArrayAdapter<String> adapter = new ArrayAdapter<String>(VODInterface.this,
android.R.layout.simple_list_item_1, android.R.id.text1, values);
listView.setAdapter(adapter);
}
}
});
mProgressDialog.dismiss();
return "";
}
protected void onPostExecute(){
//start adding to cache
super.onPostExecute("");
}
}
private void getData(){
vod = new ArrayList<VODObject>();
for(int i=1;i<MainActivity.voddb.getVODCount()+1;i++){
vod.add(MainActivity.voddb.getVOD(i+""));
if(vod.get(i-1).Icon.contains(" ")){
vod.get(i-1).Icon = vod.get(i-1).Icon.replaceAll(" ", "%20");
Log.i("u korrigjua", vod.get(i-1).Icon);
}
}
}
private void populateMovieView(){
gallery = (Gallery) findViewById(R.id.gallery1);
GalleryImageAdapter gia= new GalleryImageAdapter(this,vod);
gallery.setAdapter(gia);
gallery.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v, final int position, long id) {
// show the selected Image
/*here is the problem
*
*----------------------------/
*/
try{
LayoutInflater factory = getLayoutInflater();
View view = factory.inflate(R.layout.listview2, null);
EditText title = (EditText) view.findViewById(R.id.editText2);
title.setText(vod.get(position).title);
TextView desc = (TextView) view.findViewById(R.id.editText4);
desc.setText(vod.get(position).description);
Log.i("info", title.getText()+" "+desc.getText());
}
catch(Exception ee){
Log.i("info", ee.getMessage()+" nnn");
}
/*----------------------*/
try{
imgview.setImageBitmap(getImageFromSD(vod.get(position).Icon));
}
catch(Exception ee){
imgview.setImageResource(R.drawable.untitled);
}
}
});
}
public static Bitmap getImageFromSD(String url){
String path = Environment.getExternalStorageDirectory().toString();
File imgFile = new File(path+"/"+WebHelper.getFilenameFromUrl(url));
Bitmap myBitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath());
return myBitmap;
}
private void saveImageToSD(Bitmap bmp,String url) throws IOException {
String path = Environment.getExternalStorageDirectory().toString();
OutputStream fOut = null;
File file = new File(path, "/"+WebHelper.getFilenameFromUrl(url));
fOut = new FileOutputStream(file);
bmp.compress(Bitmap.CompressFormat.JPEG, 100, fOut);
fOut.flush();
fOut.close();
MediaStore.Images.Media.insertImage(getContentResolver(),file.getAbsolutePath(),file.getName (),file.getName());
}
private boolean FileExciste(String url){
String path = Environment.getExternalStorageDirectory().toString();
File file = new File(path, "/"+WebHelper.getFilenameFromUrl(url));
return file.exists();
}
AND this is my XML
<?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:background="#drawable/vod"
android:orientation="vertical" >
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="top" >
<ListView
android:id="#+id/listView1"
android:layout_width="274dp"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginBottom="20dp"
android:layout_marginLeft="20dp"
android:layout_marginTop="20dp"
android:background="#color/translucent_bblack" >
</ListView>
<LinearLayout
android:id="#+id/movieView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/translucent_black"
android:orientation="vertical"
android:visibility="invisible" >
<Gallery
android:id="#+id/gallery1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="20dp"
android:background="#color/translucent_bblack" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<ImageButton
android:id="#+id/imageView2"
android:layout_width="400dp"
android:layout_height="fill_parent"
android:layout_marginBottom="20dp"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:background="#drawable/bord" />
<LinearLayout
android:id="#+id/MovieDesc"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:layout_marginBottom="20dp"
android:layout_marginRight="20dp"
android:background="#color/translucent_bblack"
android:orientation="vertical" >
<TextView
android:id="#+id/editText1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="30dp"
android:layout_marginTop="30dp"
android:inputType="textPersonName"
android:text="Title:"
android:textColor="#FFFFFF"
android:textSize="20sp"
android:textStyle="bold" >
</TextView>
<TextView
android:id="#+id/editText2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="30dp"
android:textColor="#FFFFFF"
android:textSize="20sp"
android:textStyle="bold" />
<TextView
android:id="#+id/editText3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="30dp"
android:layout_marginTop="30dp"
android:text="Description:"
android:textColor="#FFFFFF"
android:textSize="20sp"
android:textStyle="bold" />
<TextView
android:id="#+id/editText4"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="30dp"
android:textColor="#FFFFFF"
android:textSize="20sp"
android:textStyle="bold" />
<TextView
android:id="#+id/editText5"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="30dp"
android:layout_marginTop="60dp"
android:text="Duration:"
android:textColor="#FFFFFF"
android:textSize="20sp"
android:textStyle="bold" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
</RelativeLayout>
Declare your TextViews as field as like as ImageView---- "imgview" as follows...
public ImageView imgview;
public TextView title;
public TextView desc;
Initialize them in onCreate method as "imgview"
imgview = (ImageView)this.findViewById(R.id.imageView2);
title = (TextView) view.findViewById(R.id.editText2);
desc = (TextView) view.findViewById(R.id.editText4);
And update your gallery.setOnItemClickListener code as follows...
gallery.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View v, final int position, long id) {
title.setText(vod.get(position).title);
desc.setText(vod.get(position).description);
Log.i("info", title.getText()+" "+desc.getText());
imgview.setImageBitmap(getImageFromSD(vod.get(position).Icon));
}
});
I searched for these issues and tried most of the given answers but my issue is not solved yet.
My Grid view has around 10-12 items and and each item has a ImageView and a TextView. image and the texts are dynamically loading from resources.
Issue 1 : When the grid is scrolling the item order changes. first items goes to down and the last items coming to top
Issue 2: When an Admob ad loads in the bottom of the screen entire Grid items are mixing up.Even without any scrolling.
Issue 3: Currently I have put the onClickListeners to the ImageView Only. How do I add the same OnclickListener to the relevant TextView as well
I have used a common gridview generation code found every where in the net.
Here is my code
public class ImageAdapter extends BaseAdapter{
Context myContext;
public ImageAdapter(Context _myContext){
myContext = _myContext;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
View MyView = convertView;
try{
if ( convertView == null ){
LayoutInflater li = ((Activity)myContext).getLayoutInflater();
MyView = li.inflate(R.layout.weather_grid, null);
TextView tv = (TextView)MyView.findViewById(R.id.grid_item_text);
Resources res = getResources();
String[] items = res.getStringArray(R.array.weather_items);
final String[] titles = new String[items.length];
int x = 0;
for(String item:items){
titles[x]=item;
x++;
}
// getStringFromRes(titles[position]);
tv.setText(titles[position]);
// Add The Image!!!
final ImageView iv = (ImageView)MyView.findViewById(R.id.grid_item_image);
Class<drawable> resources = R.drawable.class;
Field[] fields = resources.getFields();
String[] imageName = new String[fields.length];
int index = 0;
for( Field field : fields )
{
if(field.getName().startsWith("weather")){
imageName[index] = field.getName();
index++;
}
}
iv.setImageResource(getDrawable(myContext, imageName[position]));
iv.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
System.out.println("Clicked Item = " + titles[position]);
Bundle b = new Bundle();
if(titles[position].equals("Weather Overview")){
startActivity(new Intent(WeatherGridActivity.this, WeatherActivity.class));
}
if(titles[position].equals("Current Weather")){
b.putString("display", "current");
Intent intent = new Intent(WeatherGridActivity.this,WeatherActivity.class);
intent.putExtras(b);
startActivityForResult(intent, 0);
//startActivity(new Intent(WeatherGridActivity.this, WeatherActivity.class));
}
if(titles[position].equals("Ask a Question")){
startActivity(new Intent(WeatherGridActivity.this, AskQuestionActivity.class));
}
if(titles[position].equals("Average Temperature")){
startActivity(new Intent(WeatherGridActivity.this, AverageTemperatureActivity.class));
}
}
});
}
}catch(Exception e){
System.out.println("Error Occured = " + e.getMessage());
e.printStackTrace();
}
return MyView;
}
#Override
public Object getItem(int arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public long getItemId(int arg0) {
// TODO Auto-generated method stub
return 0;
}
#Override
public int getCount() {
return 10;
}
public int getDrawable(Context context, String name){
Assert.assertNotNull(context);
Assert.assertNotNull(name);
return context.getResources().getIdentifier(name,"drawable", context.getPackageName());
}
public String getStringFromRes(String name){
try{
int resId = (Integer) R.string.class.getField(name).get(null);
// Toast.makeText(MyContext, getResources().getString(resId), Toast.LENGTH_LONG).show();
return getResources().getString(resId);
}catch(Exception e){
// no such string
return "empty";
}
}
}
Here is the xml
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:ads="http://schemas.android.com/apk/lib/com.google.ads"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/bg"
android:orientation="vertical" >
<GridView
android:id="#+id/weather"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/bg"
android:columnWidth="70dp"
android:gravity="center_horizontal"
android:horizontalSpacing="20dp"
android:numColumns="auto_fit"
android:padding="20dp"
android:stretchMode="columnWidth"
android:tileMode="repeat"
android:verticalSpacing="20dp" >
</GridView>
<ImageView
android:id="#+id/back_button"
style="#style/book_button" />
<com.google.ads.AdView
android:id="#+id/adView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
ads:adSize="BANNER"
ads:adUnitId="dummy id"
ads:loadAdOnCreate="true"
ads:testDevices="TEST_EMULATOR, TEST_DEVICE_ID" />
</LinearLayout>
</ScrollView>
I have added the RelativeLayout instead of LinerLayout and ScrollViews but now the entire Grid doesn't display but the ads displaying properly.
Here is the new xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:ads="http://schemas.android.com/apk/lib/com.google.ads"
android:id="#+id/home_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/bg"
>
<GridView
android:id="#+id/home_grid"
android:layout_width="wrap_content"
android:layout_height="0dip"
android:columnWidth="100dp"
android:rowHeight="30dp"
android:gravity="center_horizontal"
android:horizontalSpacing="5dp"
android:numColumns="auto_fit"
android:stretchMode="none"
android:tileMode="repeat"
android:verticalSpacing="30dp"
>
</GridView>
<com.google.ads.AdView
android:layout_alignParentBottom="true"
android:id="#+id/adView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
ads:adSize="BANNER"
ads:adUnitId="dummy id"
ads:loadAdOnCreate="true"
ads:testDevices="TEST_EMULATOR, TEST_DEVICE_ID"
android:layout_centerHorizontal="true" />
</RelativeLayout>
Your answers are highly appreciated
Thanks
Here is the working code. This fix the scrolling issue,the Admob issue and the onClickListener issue as well.
public class ImageAdapter extends BaseAdapter{
Context myContext;
public ImageAdapter(Context _myContext){
myContext = _myContext;
layoutInflater = LayoutInflater.from(myContext);
Resources res = getResources();
String[] items = res.getStringArray(R.array.weather_items);
titles = new String[items.length];
int x = 0;
for(String item:items){
titles[x]=item;
x++;
}
Class<drawable> resources = R.drawable.class;
Field[] fields = resources.getFields();
imageName = new String[fields.length];
int index = 0;
for( Field field : fields ){
if(field.getName().startsWith("weather")){
imageName[index] = field.getName();
index++;
}
}
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
// View MyView = convertView;
View grid = null;
try{
if ( convertView == null ){
grid = new View(myContext);
// LayoutInflater li = ((Activity)myContext).getLayoutInflater();
grid = layoutInflater.inflate(R.layout.weather_grid, null);
}else{
grid = (View)convertView;
}
TextView tv = (TextView)grid.findViewById(R.id.grid_item_text);
tv.setText(titles[position]);
ImageView iv = (ImageView)grid.findViewById(R.id.grid_item_image);
iv.setImageResource(getDrawable(myContext, imageName[position]));
iv.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
executeListners(position);
}
});
tv.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
executeListners(position);
}
});
}catch(Exception e){
System.out.println("Error Occured = " + e.getMessage());
e.printStackTrace();
}
return grid;
}
#Override
public Object getItem(int arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public long getItemId(int arg0) {
// TODO Auto-generated method stub
return 0;
}
#Override
public int getCount() {
return 10;
}
public int getDrawable(Context context, String name){
Assert.assertNotNull(context);
Assert.assertNotNull(name);
return context.getResources().getIdentifier(name,"drawable", context.getPackageName());
}
public String getStringFromRes(String name){
try{
int resId = (Integer) R.string.class.getField(name).get(null);
// Toast.makeText(MyContext, getResources().getString(resId), Toast.LENGTH_LONG).show();
return getResources().getString(resId);
}catch(Exception e){
return "empty";
}
}
}
The xml files has no changes. This works with either RelativeLayout or with a LinearLayout
I would like to implement that kind of gallery, but with the difference of getting images remotly.
The idea is to update the view only when an image has been downloaded.
=> I need to update the view only when going to onComplete.
Please find below my code :
public class displayAlbums extends Activity {
private static String URL_GRAPH_API = "https://graph.facebook.com/";
private static final String TAG = "displayAlbums";
private ArrayList<Bitmap> thumbnails = new ArrayList<Bitmap>();
private ArrayList<URI> thumbnails_uri = new ArrayList<URI>();
private ImageAdapter imageAdapter;
private int imageCounter = 0;
public boolean[] thumbnailsselection;
public Albums album;
private Context displayAlbums_context;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.galleryitem);
this.displayAlbums_context = this;
Log.d(TAG, "on create");
findViewById(R.id.itemCheckBox).setVisibility(View.GONE);
final GridView imagegrid = (GridView) findViewById(R.id.PhoneImageGrid);
populateThumbnailsList();
processThumbnailsToDownload(thumbnails_uri, new PictureRequestListener() {
#Override
public void onComplete(Bitmap bitmap) {
if(imageAdapter == null) {
Log.d(TAG, "image adapter is null");
imageAdapter = new ImageAdapter(displayAlbums_context);
imagegrid.setAdapter(imageAdapter);
}
imagegrid.setId(imageCounter);
thumbnails.add(bitmap);
imageCounter++;
//imageAdapter.notifyDataSetChanged();
}
});
}
public void processThumbnailsToDownload(ArrayList<URI> thumbnails_uri, final FbRequestListener listener) {
Log.v(TAG,"processThumbnailsToDownload CALLED");
for(URI thumbnail_uri : thumbnails_uri ) {
new HttpConnection(ConnectionManager.getConnectionHandler(listener)).bitmap(thumbnail_uri);
}
}
public void populateThumbnailsList() {
URI uri = null;
for(final Albums album : LoadObjects.albums ) {
Bundle parameters = new Bundle();
parameters.putString("access_token", FbpicturesActivity.mFacebook.getAccessToken());
try {
uri = new URI(URL_GRAPH_API + album.getAid() + "/picture" + "?" +Util.encodeUrl(parameters) );
thumbnails_uri.add(uri);
} catch (URISyntaxException e) {
e.printStackTrace();
}
}
}
public class ImageAdapter extends BaseAdapter {
private LayoutInflater mInflater;
private Context myContext;
public ImageAdapter(Context displayAlbums_context) {
Log.v(TAG,"IMAGE ADAPTER");
mInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
public int getCount() {
Log.d(TAG,"thumnail_uri size"+thumbnails_uri.size());
return thumbnails_uri.size();
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public View getView(final int position, View convertView, ViewGroup parent) {
Log.v(TAG,"GET VIEW CALLED");
ViewHolder holder;
if (convertView == null) {
holder = new ViewHolder();
convertView = mInflater.inflate(R.layout.galleryitem, null);
holder.imageview = (ImageView) convertView.findViewById(R.id.thumbImage);
holder.checkbox = (CheckBox) convertView.findViewById(R.id.itemCheckBox);
convertView.setTag(holder);
}
else {
holder = (ViewHolder) convertView.getTag();
}
//holder.checkbox.setId(position);
//holder.imageview.setId(position);
Log.d(TAG,"thumnail size"+thumbnails.size());
Log.d(TAG,"thumnail position"+thumbnails.get(position));
holder.imageview.setImageBitmap(thumbnails.get(position));
holder.checkbox.setChecked(true);
holder.id = position;
return convertView;
}
}
}
class ViewHolder {
ImageView imageview;
CheckBox checkbox;
int id;
}
galleryItem.xml :
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_height="fill_parent">
<Button android:id="#+id/selectBtn"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:text="Select" android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:minWidth="200px" />
<GridView android:id="#+id/PhoneImageGrid"
android:layout_width="fill_parent" android:layout_height="fill_parent"
android:numColumns="auto_fit" android:verticalSpacing="10dp"
android:horizontalSpacing="10dp" android:columnWidth="90dp"
android:stretchMode="columnWidth" android:gravity="center"
android:layout_above="#id/selectBtn" />
<ImageView android:id="#+id/thumbImage" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_centerInParent="true" />
<CheckBox android:id="#+id/itemCheckBox" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_alignParentRight="true"
android:layout_alignParentTop="true" />
</RelativeLayout>
Please note i have added some Log.v to understand when getView is called :
=> http://pastebin.com/L9PYBYDa
questions :
1) Why getView is called 4 times ?
2) Why holder.imageview.setImageBitmap(thumbnails.get(position)) returns java.lang.IndexOutOfBoundsException: Invalid index 1, size is 1 ?
3) Do you have any advice to implement my gallery with remote image ?
Thank you very much for your help
1) getView will be called at least (numberOfVisibleRows+ 1 or +2) times. I say at least because it can be called as many times as the system wants. There is no guarantee on that.
2)Because thumbnails is lower than size 2 or is null. You have to debug to see that
3) Check this out