Hi I am developing an app in android where I use a subclass that extends BaseExpandableListAdapter. Right now I have problem to combine ImageView and TextView in the list that is showing. Yesterday I found this link on stackoverflow that helped me to make this combination.
Overlay text over imageview in framelayout programmatically - Android
So it works FINE! - until I click on a listItem. The app chrash and the logcat tells me that
"android.widget.RelativeLayout" cannot be cast to android.widget.ImageView. This exception comes the getGroupView() in the class that extends BaseExpandableListAdapter . Why does this happen? (RelativeLayout extends View).
Am I completely on the wrong way when I try to return a RelativeLayout instead of an ImageView?
Here's my code from getGroupView (I'm a bit messy because I am in a teststate) :
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
ImageView row = (ImageView) convertView;
RelativeLayout rLayout = new RelativeLayout(mContext);
LayoutParams rlParams = new LayoutParams(LayoutParams.FILL_PARENT
,LayoutParams.FILL_PARENT);
rLayout.setLayoutParams(rlParams);
if(row == null) {
row = new ImageView(mContext);
}
row.setImageResource(R.drawable.ic_launcher);
row.setScaleType(ImageView.ScaleType.FIT_START);
RelativeLayout.LayoutParams tParams = new RelativeLayout.LayoutParams
(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
tParams.addRule(RelativeLayout.CENTER_HORIZONTAL, RelativeLayout.TRUE);
tParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, RelativeLayout.TRUE);
TextView text=new TextView(mContext);
text.setText("GOLDEN Gate");
text.setTextColor(Color.WHITE);
text.setTypeface(Typeface.DEFAULT_BOLD);
text.setLayoutParams(tParams);
rLayout.addView(row);
rLayout.addView(text);
return rLayout;
}
The statement ImageView row = (ImageView) convertView; gives the exception because u r trying to convert the RelativeLayout to ImageView.
You must return the convertView in getViewGroup() method but you are returning the RelativeLayout i.e., return rLayout;
Solution :
Add a ImageView and TextView inside a RelativeLayout. Set that layout for ListItem by inflating it inside getView() method and assign the inflated layout to convertView. Return the convertView in getView() method;
Related
I am using an adaptor to generate a view for each of several items. The view needs to show an image with centered text below it. I create a linear layout and add an image view and text view.
To show the problem I have changed the background colors to green for the linear layout and red for the text view...
Obviously the text is showing left aligned instead of centered. Here is the simple code in the adaptor GetView method...
public override View GetView(int position, View convertView, ViewGroup parent)
{
ImageView imageView = new ImageView(_context);
LinearLayout.LayoutParams imageViewParam = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MatchParent, LinearLayout.LayoutParams.WrapContent);
imageView.LayoutParameters = imageViewParam;
imageView.Id = 1000 + position;
imageView.SetImageResource(Resource.Drawable.Code);
TextView textView = new TextView(_context);
LinearLayout.LayoutParams textViewParam = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MatchParent, LinearLayout.LayoutParams.WrapContent);
textView.LayoutParameters = textViewParam;
textView.Text = OPTIONS_TEXT[position];
textView.SetBackgroundColor(Color.Red);
textView.SetForegroundGravity(GravityFlags.CenterHorizontal);
LinearLayout linear = new LinearLayout(_context);
linear.LayoutParameters = new GridView.LayoutParams(200, 172);
linear.SetBackgroundColor(Color.Green);
linear.Orientation = Orientation.Vertical;
linear.AddView(imageView);
linear.AddView(textView);
return linear;
}
As far as I can work out, you cannot set the layout_gravity setting when generating the view programmatically and so I tried setting the foreground gravity but has no effect at all.
I have tried everything I can think of but nothing gets that text centered!
Set gravity center to LinearLayout.LayoutParams of TextView i.e.
textViewParam.gravity = Gravity.CENTER;
So I'm creating ImageView and TextView in the runtime and I want the TextView to be placed right of the ImageView.
I'm trying this simple code:
private void loadContent(Module module) {
this.removeAllViewsInLayout();
this.addView(getModuleIconView(module));
this.addView(getModuleNameView(module));
}
private ImageView getModuleIconView(Module module) {
ImageView view = new ImageView(context);
view.setImageResource(module.getIconResId());
android.view.ViewGroup.LayoutParams params = new LayoutParams(120, 120);
view.setLayoutParams(params);
view.setId(1); //seting some id for the view
return view;
}
private TextView getModuleNameView(Module module) {
TextView view = new TextView(context);
view.setText(module.getName());
params.addRule(RelativeLayout.RIGHT_OF, 1); //hoping for view to be placed right of the ImageView which id was set to 1
return view;
}
What Do I do wrong here? The TextView is placed on my ImageView ignoring the RIGHT_OF
Need to mention the class inherits from RelativeLayout
It was my stupid mistake. Third method leaks setLayoutParams
So correct method body is:
private TextView getModuleNameView(Module module) {
TextView view = new TextView(context);
view.setText(module.getName());
params.addRule(RelativeLayout.RIGHT_OF, 1);
view.setLayoutParams(params);
return view;
}
I want my TextView to appear below my ImageView in a RelativeLayout that is going into a GridView. I've tried:
public override View GetView(int position, View convertView, ViewGroup parent)
{
RelativeLayout rl = new RelativeLayout(context);
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.FillParent, ViewGroup.LayoutParams.FillParent);
ImageView imageView;
TextView tv;
imageView = new ImageView(context);
imageView.LayoutParameters = new GridView.LayoutParams(250, 250);
imageView.SetScaleType(ImageView.ScaleType.CenterCrop);
imageView.SetPadding(8, 8, 8, 8);
imageView.SetImageResource(thumbIds[position]);
imageView.Id = position;
lp.AddRule(LayoutRules.Below, position);
lp.AddRule(LayoutRules.CenterHorizontal);
tv = new TextView(context);
tv.Text = stringIds[position].ToString();
tv.SetTextSize(Android.Util.ComplexUnitType.Dip, 20);
tv.SetTextColor(Android.Graphics.Color.WhiteSmoke);
tv.LayoutParameters = lp;
rl.AddView(imageView);
rl.AddView(tv);
return rl;
}
But the TextView always shows up on top of the ImageView.
Check out this question.
When you call rl.AddView(tv), you should include the LayoutParams rl.AddView(tv, lp).
You have to use
imageView.setLayoutParams(lp) in order to assign the params to your view.
How do you setLayoutParams() for an ImageView?
Since my content is not dynamic, I worked around the issue by simply editing my image in Paint and placing text below the image. Then I made that the background for the ImageView.
I'm trying to build a gallery with text below the image but although I've followed every response founded in here I've yet to accomplish my objective.
public View getView(int position, View convertView, ViewGroup parent) {
LinearLayout ll = new LinearLayout(mContext);
ll.setOrientation(LinearLayout.VERTICAL);
ImageView i = new ImageView(mContext);
i.setImageResource(mImageIds[position]);
i.setScaleType(ImageView.ScaleType.FIT_XY);
i.setLayoutParams(new Gallery.LayoutParams(150, 150));
TextView tv = new TextView(ll.getContext());
tv.setTag(mText[position]);
tv.setText(mText[position]);
tv.setLayoutParams(new Gallery.LayoutParams(48, 48));
ll.addView(tv);
// The preferred Gallery item background
//i.setBackgroundResource(mGalleryItemBackground);
return ll;
//return i;
}
I don't know why (and maybe it's the dumbest thing) but my images don't appear:)
I believe you forgot to add the image view to the linear layout, simply add:
ll.addView(i);
Also you are not recycling the convertView which could cause problems unless you have very few images and little to no scrolling of the grid.
You should check if convertView is null and if it is not simply change the text and image of the existing convertView.
Here is a good example for a custom grid view:
http://vikaskanani.wordpress.com/2011/07/20/android-custom-image-gallery-with-checkbox-in-grid-to-select-multiple/
I'm working on an Android app that utilizes a ListView, in which each row is comprised of a text view and a progress bar. Things work smoothly unless the user has to scroll through a long list.
ProgressBars start taking on the progress of other ProgressBars not currently visible on the screen.
I understand that this is a common issue that stems from the implementation of GetView, but I'm wondering what the best course of action is to take with ProgressBars.
GetView:
public View getView(int position, View convertView, ViewGroup parent){
View row = convertView;
ViewWrapper wrapper;
ProgressBar myProgressBar;
int initProgress = myData.get(position).getProgress();
if (row == null){
LayoutInflater inflater = context.getLayoutInflater();
row = inflater.inflate(R.layout.row, null);
wrapper = new ViewWrapper(row);
row.setTag(wrapper);
}
else{
wrapper = (ViewWrapper)row.getTag();
}
RowModel model = getModel(position);
wrapper.getPid().setText(model.toString());
myProgressBar = wrapper.getProgressBar();
myProgressBar.setProgress(initProgress);
myProgressBar.setMax(100);
myProgressBar.setTag(new Integer(position));
return row;
}
ViewWrapper:
public class ViewWrapper {
View base;
TextView pid = null;
ProgressBar pb= null;
ViewWrapper(View base){
this.base = base;
}
TextView getPid(){
if(pid == null){
pid = (TextView)base.findViewById(R.id.pid);
}
return(pid);
}
ProgressBar getProgressBar(){
if(pb== null){
pb= (ProgressBar)base.findViewById(R.id.progressbar);
}
return(pb);
}
}
It seems that the issue is related to:
myProgressBar = wrapper.getProgressBar();
because that ProgressBar starts getting the behavior of a recycled ProgressBar. However, I want it to have its own behavior.
What's the best way to alleviate this? Thanks.
You may need to inflate the layout each time and not re-use the convertView that's passed in. This shouldn't be a problem unless you have A LOT of rows.
I had to implement a similar feature , here is what I did . I implemented the following outside getview
OnTouchListener - to listen to seekbar touch events
OnKeyListener - to listen to dpad and trakball event for the seekbar
I set these listeners for the seekbars from getView
Whenever the listeners were called , I would find the seekbars parent , then do the findviewbyid from the parent to the textview.
So now I have the textview which I have to update, and the seekbar. All I need to do was set the text from the array.
here is some code to help you.
private OnTouchListener touchListener = new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
View parent = (View) v.getParent();
TextView textView = (TextView) parent
.findViewById(R.id.id_grade_tooltip);
if (textView == null) {
} else {
SeekBar seekBar = (SeekBar) v;
textView.setText(String.valueOf(seekBar.getProgress())
+ "%");
}
return false;
}
};