I get an error when i try to use the a recycled gridview every time if convertView != null then i get an error here is my source code.
it will give me an error right at text = (TextView) convertView; in the else statment. I am really lost here, I would just stop recycling the views but then its to heavy on memory and its choppy scrolling
$ here is the imageadapter.java
public View getView(int position, View convertView, ViewGroup parent) {
RelativeLayout lay;
ImageView image;
TextView text;
if (convertView == null) {
Log.d("height", "Width = " + width);
lay = new RelativeLayout(mContext);
image = new ImageView(mContext);
text = new TextView(mContext);
//text.setText("This is a test");
text.setTextSize(14);
text.setTextColor(Color.WHITE);
text.setGravity(Gravity.LEFT | Gravity.TOP);
text.setPadding(2, 2, 2, 2);
text.setBackgroundColor(Color.parseColor("#80000000"));
RelativeLayout.LayoutParams textLayout = new RelativeLayout.LayoutParams(
(int) Math.round(width / 2.0),
(int) Math.round(width / 8.3));
textLayout.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
text.setLayoutParams(textLayout);
MarginLayoutParams textMarginFix = (ViewGroup.MarginLayoutParams) text
.getLayoutParams();
textMarginFix.setMargins(0, 0, 0, (int) Math.round(width / 45.0));
text.setLayoutParams(textMarginFix);
image.setLayoutParams(new LayoutParams((int) Math
.round(width / 2.0), (int) Math.round(width / 2.0)));
image.setScaleType(ImageView.ScaleType.CENTER_CROP);
//image.setImageResource(mThumbIds[position]);
lay.setLayoutParams(new GridView.LayoutParams((int) Math
.round(width / 2.0), (int) Math.round(width / 2.0)));
lay.setBackgroundResource(R.drawable.shadowimage);
lay.setPadding(5, 5, 15, 15);
//lay.setId(mThumbIds[position]);
//lay.addView(image);
//lay.addView(text);
}
else
{
text = (TextView) convertView;
image = (ImageView) convertView;
lay = (RelativeLayout) convertView;
}
image.setImageResource(mThumbIds[position]);
text.setText("This is a test");
lay.addView(image);
lay.addView(text);
return lay;
}
$here is where i call the imageadapter from another class
#Override
public Object instantiateItem(View container, int position) {
View contentView;
switch (position) {
case 0:
LayoutInflater mInflater = LayoutInflater.from(mContext);
View contentView = mInflater.inflate(R.layout.image_grid_view, null);
Display display = mContext.getWindowManager().getDefaultDisplay();
final int width = display.getWidth();
int height = display.getHeight();
float scale = mContext.getResources().getDisplayMetrics().density;
GridView gridview = (GridView) contentView.findViewById(R.id.gridview);
gridview.setAdapter(new ImageAdapter(mContext, width, height, scale));
gridview.setFocusable(true);
gridview.requestFocus();
gridview.setOnItemClickListener(itemClickListener);
((ViewPager) container).addView(contentView, 0);
break;
...return contentView
convertView is the view that entirely represents one item in your GridView. If that is a TextView, it will be a TextView, if it is an entire layout, you will receive the entire layout and so on.
So how do you know and define what is "the view that represents one item"? Simple, it is whatever you create when convertView == null and then return from getView.
Simply you are receiving a used item and you are just modifying it to update it to the appropriate content. So you should utilize type casting to get this View you receive in a format you want.
Code like below will get you what you want without redoing things you don't need to do (aka you do not need to re-add child Views from a convertView, only a new view):
public View getView(int position, View convertView, ViewGroup parent) {
RelativeLayout lay;
ImageView image;
TextView text;
if (convertView == null) {
// Setup your 'item view'
lay = new RelativeLayout(mContext);
image = new ImageView(mContext);
text = new TextView(mContext);
// Do all your customizing stuff (aka size, color, format, padding layout params)
lay.addView(image, 0);
lay.addView(text, 1);
} else {
lay = (RelativeLayout) convertView;
image = (ImageView) lay.getChildAt(0);
text = (TextView) lay.getChildAt(1);
}
// Set content for your image and text
return lay;
}
[ADDITION]
Further, you have the code
image.setImageResource(mThumbIds[position]);
text.setText("This is a test");
lay.addView(image);
lay.addView(text);
return lay;
outside the if and the else, what this means is that you are trying to add a subview EVERY TIME a cell's view is asked for. You really only need to add views to lay within the if portion of your routine.
[ORIGINAL]
Most likely convertView is your parent, and all other views are sub to it. In your else clause, all you do is set each one to the SAME EXACT THING. How can the convertView be three completely different things all at once.
Most likely it needs to be:
text = (TextView) convertView.SomeTextViewSubToConvertView;
image = (ImageView) convertView.SomeImageViewSubToConvertView;
lay = (RelativeLayout) convertView.SomeRelativeLayoutSubToConvertView;
Related
I am currently working on changing the height of a layout programatically.
Here's a snippet of the layout initialization :
setContentView(R.layout.activity_main);
LayoutInflater inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View pagerItemInflater = (View) inflater.inflate(R.layout.activity_main, null);
getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
LayoutResize layoutResize = new LayoutResize();
RelativeLayout relativeViewPager =(RelativeLayout) findViewById(R.id.relativeViewPager);
int relativeViewPagerHeight = layoutResize.height(75, displayMetrics);
ViewGroup.LayoutParams viewPagerParams = relativeViewPager.getLayoutParams();
viewPagerParams.height = relativeViewPagerHeight;
relativeViewPager.setLayoutParams(viewPagerParams);
RelativeLayout viewPagerItem =(RelativeLayout) pagerItemInflater.findViewById(R.id.viewPagerItem);
int viewPagerItemWidth = layoutResize.width(100, displayMetrics);
int viewPagerItemHeight = layoutResize.height(28, displayMetrics);
RelativeLayout.LayoutParams viewPagerItemParams = new RelativeLayout.LayoutParams(viewPagerItemWidth, viewPagerItemHeight);
//ViewGroup.LayoutParams viewPagerItemParams = viewPagerItem.getLayoutParams();
viewPagerItemParams.height = viewPagerItemHeight;
viewPagerItem.setLayoutParams(viewPagerItemParams);
The problem is, I can't get the second one which is viewPagerItem to resize to 28% of screen. When I use log, the viewPagerItemHeight shows the appropiate height I wanted, but the layout doesn't resize as expected.
I've read around and some people said that View pagerItemInflater = (View) inflater.inflate(R.layout.activity_main, null); null is supposed to be the root class right? The R.layout.activity_main? But I can't use it there, it says cannot resolve method inflate(int,int)
I have this issue with loading my Bitmap image. I created a custom ImageAdapter and ImageItem for my GridLayout view. The application is supposed to take a picture, save it to the external storage, and retrieve the image from the external storage, showing it as a small thumbnail in a grid. When that image is clicked from the grid, a new Activity is started, showing the full-sized image. Everything has worked fine so far (The images get saved, and I can actually view them on the file system, the supplied path is correct), but the problem I am facing is that when I load the image, it shows up blank in the GridView, and when it is clicked upon, the new Activity also shows a blank image. I would greatly appreciate any help I can get! Here's the code:
The getView for the custom Adapter:
public View getView(int position, View convertView, ViewGroup parent) {
if(convertView == null){
final ImageItem imageItem = (ImageItem) getItem(position);
LayoutInflater li = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
LinearLayout itemLayout = (LinearLayout) li.inflate(R.layout.image_item, parent, false);
final TextView nameView = (TextView) itemLayout.findViewById(R.id.nameView);
nameView.setText(imageItem.getName());
final ImageView imageView = (ImageView) itemLayout.findViewById(R.id.imageView);
String url = imageItem.getUrl();
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
//Bitmap bitmap = BitmapFactory.decodeFile(url);
Drawable d = Drawable.createFromPath(url);
imageView.setImageDrawable(d);
imageView.setLayoutParams(new LinearLayout.LayoutParams(WIDTH, HEIGHT));
imageView.setPadding(PADDING, PADDING, PADDING, PADDING);
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
return itemLayout;
} else {
return convertView;
}
}
Very simple, I'm using list view from this tutorial and I have tried using
AutoFitTextView and also AutoResizeTextView, I have made the row MATCH_PARENT for its width also height, I made the different TextViews MATCH_PARENT.
I even tried getting the screenWidth, subtracting it for the image width and making that result the width of the textView and then making it resize, and still doesn't work.
Here is my getView implemented in my CustomList class:
public View getView(int position, View view, ViewGroup parent) {
LayoutInflater inflater = context.getLayoutInflater();
View rowView= inflater.inflate(R.layout.list_single, null, true);
TableRow tbrow = (TableRow) rowView.findViewById(R.id.idTableRow1);
tbrow.setLayoutParams(new TableRow.LayoutParams(TableRow.LayoutParams.MATCH_PARENT,TableRow.LayoutParams.MATCH_PARENT));
ImageView imageView = (ImageView) rowView.findViewById(R.id.img);
AutoResizeTextView tv = new AutoResizeTextView(context);
((TableRow)imageView.getParent()).addView(tv);
tv.setGravity(Gravity.CENTER);
tbrow.setGravity(Gravity.CENTER);
//Fix for android 4.0.4 versions and earlier
final String DOUBLE_BYTE_SPACE = "\u3000";
String fixString = "";
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB_MR1
&& android.os.Build.VERSION.SDK_INT <= android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) {
fixString = DOUBLE_BYTE_SPACE;
}
tv.setLayoutParams(new TableRow.LayoutParams(TableRow.LayoutParams.MATCH_PARENT, TableRow.LayoutParams.MATCH_PARENT, 1f));
tv.setText(fixString + web[position] + fixString);
imageView.setImageDrawable(imageId[position]);
if(setParameters){
imageView.setLayoutParams(params);
}
return rowView;
}
Please I'm desperate in search of this, I have looked everywhere and none helped me...
Thanks in advance.
I need to generate some ImageView inside the getView method.
I will generate them inside this layout :
<LinearLayout
android:id="#+id/layoutBaby"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:orientation="horizontal" >
So the images will be added horizontally automatically (because the orientation).
This is how i add those images :
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
for(int childId : dbHelper.getChildrenIdBySchedule(getItem(position).getId()))
{
ImageView imgBaby = new ImageView(context);
imgBaby.setLayoutParams(params);
String image = dbHelper.getChildImage(childId);
File imgFile = new File(image);
if(imgFile.exists())
{
Bitmap myBitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath());
imgBaby.setImageBitmap(myBitmap);
}
else
{
imgBaby.setImageResource(R.drawable.ic_launcher);
}
holder.layoutBaby.addView(imgBaby);
}
I have debug the code above to make sure its called multiple times (based on dbHelper.getChildrenIdBySchedule).
This code working if theres only 1 ImageView, however if there is more than 1 ImageView, only the lastest added ImageView is vissible.
For example, if theres 2 ImageViews, although both of them has been added (i debug the code), only the 2nd ImageView is visible.
Feel free to ask me anything, and Thanks for your time.
You can manage it with HorizontalScrollView :
public View getView(int position, View view, ViewGroup viewgroup) {
ViewHolder holder = new ViewHolder(); // our view holder of the row
if (view == null) {
HorizontalScrollView hr = new HorizontalScrollView(con);
LinearLayout layout = new LinearLayout(con);
layout.setLayoutParams(new LinearLayout.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
for(int childId : dbHelper.getChildrenIdBySchedule(getItem(position).getId()))
holder.image = new ImageView(con);
layout.addView(holder.image);
String image = dbHelper.getChildImage(childId);
File imgFile = new File(image);
if(imgFile.exists())
{
Bitmap myBitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath());
holder.image.setImageBitmap(myBitmap);
}
else
holder.image.setImageResource(R.drawable.ic_launcher);
}
hr.addView(layout);
view = hr;
view.setTag(holder);
}
holder = (ViewHolder) view.getTag();
return view;
}
For more info, refer this
I want to put this design in mi xml. At first one header and one picture once, and then many row to show information about the photo. My problem is that when I put all in a RelativeLayout when I select the first row I select the photo, header and first row. Therefore I have to put in two xml the main element (Photo and header) and in other xml all the rows. How can I inflate in Listview two xml? I don't know how I can do this.
I can't post images therefore the structure will be:
(One item in listview)
1) HEADER and PHOTO don't repeat
2) ROWS - more than one row
It is like to put a header into one row of listview. Because I want to put comments in each photo and could be more than one per each photo.
I had all in the same xml but with this format I had the problem when click on one row.
The photo and user details only must be shown once and rows depends on each photo, there are photos with more than one rows. Therefore I think the best option will be to do two xml files and inflate it from java code, but I don't know to do this. If someone have another best option will be accepted.
And my getView code is the following:
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
ViewHolder holder;
Object repeat = MyArrList.get(position).get("Repeat");
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
int height = metrics.heightPixels;
int width = metrics.widthPixels;
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) mContext
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.activity_column, null);
holder = new ViewHolder();
holder.imageView = (ImageView) convertView.findViewById(R.id.ColImgPath);
//Userdetails
holder.tvU = (TextView) convertView.findViewById(R.id.tvU);
holder.tvUN = (TextView) convertView.findViewById(R.id.tvUN);
holder.ivProfilePhoto = (ImageView) convertView.findViewById(R.id.profilephoto);
//Accessory details
holder.tvN = (TextView) convertView.findViewById(R.id.tvN);
holder.tvB = (TextView) convertView.findViewById(R.id.tvB);
holder.tvP = (TextView) convertView.findViewById(R.id.tvP);
holder.tvS = (TextView) convertView.findViewById(R.id.tvS);
convertView.setTag(holder);
}
else{
holder = (ViewHolder) convertView.getTag();
}
holder.imageView.setPadding(5, 5, 5, 5);
holder.imageView.setRotation(90);
if(repeat.equals("1")){
holder.imageView.setVisibility(View.VISIBLE);
holder.tvU.setVisibility(View.VISIBLE);
holder.tvUN.setVisibility(View.VISIBLE);
holder.tvU.setText(MyArrList.get(position).get("U").toString());
holder.tvUN.setText(MyArrList.get(position).get("UN").toString());
}
else {
//If the photo_id is repeated these params are not shown
holder.tvU.setVisibility(View.GONE);
holder.tvUN.setVisibility(View.GONE);
holder.imageView.setVisibility(View.GONE);
}
try {
Bitmap bmp = ((Bitmap) MyArrList.get(position).get("ImageThumBitmap"));
Bitmap photobitmap1 = Bitmap.createScaledBitmap(bmp, width/2, height/2, true);
holder.imageView.setImageBitmap((Bitmap) MyArrList.get(position).get("Photo"));
} catch (Exception e) {
// When Error
holder.imageView.setImageResource(android.R.drawable.ic_menu_report_image);
}
holder.tvN.setPadding(20, 0, 0, 0);
holder.tvN.setText(MyArrList.get(position).get("N").toString());
holder.tvB.setPadding(20, 0, 0, 0);
holder.tvBsetText(MyArrList.get(position).get("B").toString());
holder.tvP.setPadding(20, 0, 0, 0);
holder.tvP.setText(MyArrList.get(position).get("P").toString());
holder.tvS.setPadding(20, 0, 0, 0);
holder.tvS.setText(MyArrList.get(position).get("S").toString());
return convertView;
}
better you can put the Header in a separate Xml and add this into your ListView Header as follow
init listView
inflate header and add it to the list
set any adapter to listView (!!!)
set listView adapter