Adding ImageView Inside Base Adapter Programatically - android

I have a GridView adapter(For gallery used).
What i want is to put Image(Check Image) when the photo is clicked.
But I am unable to do that with this code.
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
cbClicked = false;
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.imagelayout, parent, false);
final CheckBox cb = (CheckBox) view.findViewById(R.id.name);
final ImageView img = (ImageView) view.findViewById(R.id.img);
final LinearLayout imgTop = (LinearLayout) view.findViewById(R.id.imgTop);
ImageView img2 = new ImageView(ActivityReviewUpload.this);
img2.setImageResource(R.drawable.ic_my_loc);
imgTop.addView(text);
return view;
}
And for my XML is this.
<?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">
<LinearLayout
android:id="#+id/imgTop"
android:layout_width="match_parent"
android:layout_height="120dp">
<ImageView
android:id="#+id/img"
android:layout_width="match_parent"
android:layout_height="120dip"
android:background="#color/colorBlack"
android:padding="2dp" />
</LinearLayout>
<CheckBox
android:id="#+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</RelativeLayout>
This is an example of what I'm doing.
In this example it's number,
what I'm doing is i will put just CHECK in the selected images.
The image is not showing.
what am i doing wrong in this part?
thanks

There's some problem with your BaseAdapter:
You should use ViewHolder or ReyclerView with GridLayoutManager to avoid laggy when scrolling your ListView.
Look at this block of code:
ImageView img2 = new ImageView(ActivityReviewUpload.this);
img2.setImageResource(R.drawable.ic_my_loc);
imgTop.addView(text);
Above code will be called everytime you sroll your ListView. Therefore, you always add new ImageView to each row when scrolling. You should remove it.
How to achieve what you want? Do it as below:
// declare selectedPosition = -1 in your `Adapter`
// in your get view added below code:
img.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
selectedPosition = position;
notifyDataSetChanged();
}
});
cb.setChecked(selectedPosition == position? true: false);
Those code will change checkbox state every time you click to your image.

Related

Change ImageView in a GridView Programmatically

I've set up a grid of ImageViews with TextView overlays. My ImageAdapter code is as follows:
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView;
View grid;
LayoutInflater inflater = (LayoutInflater) mContext
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (convertView == null) {
grid = new View(mContext);
grid = inflater.inflate(R.layout.image, null);
TextView textView = (TextView)grid.findViewById(R.id.mastery_text);
imageView = (ImageView)grid.findViewById(R.id.mastery_image);
grid.setLayoutParams(new GridView.LayoutParams(150, 150));
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
grid.setPadding(8, 8, 8, 8);
grid.setBackgroundResource(R.color.orange);
imageView.setImageResource(mThumbIds[position]);
} else {
grid = (View) convertView;
}
return grid;
}
The corresponding XML layout for my ImageAdapter is this:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/layout_practitioner"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ImageView
android:id="#+id/mastery_image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_gravity="bottom"
android:background="#bbffffff"
android:focusable="false"
android:focusableInTouchMode="false" >
<TextView android:id="#+id/mastery_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="0dp"
android:textColor="#color/black"
android:gravity="bottom|center"
android:textSize="12sp"
android:textAllCaps="true"
android:paddingBottom="0dp"
android:text="3/3"
/>
</LinearLayout>
</FrameLayout>
XML code for my GridView (activity class):
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<GridView xmlns:android="http://schemas.android.com/apk/res/android"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:id="#+id/gridview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:numColumns="4"
android:verticalSpacing="10dp"
android:horizontalSpacing="10dp"
android:stretchMode="columnWidth"
android:gravity="center" />
</LinearLayout>
Here is the onCreate method of my main activity:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_masteries);
GridView gridview = (GridView) findViewById(R.id.gridview);
ImageAdapter adapter = new ImageAdapter(this);
gridview.setAdapter(adapter);
gridview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v,
int position, long id) {
Toast.makeText(Masteries.this, "" + position,
Toast.LENGTH_SHORT).show();
}
});
}
I want to, after initializing the grid with the images, change one of the ImageViews from my activity class, given its position on the grid. How would I do that?
I'm not asking to change the image in response to an onItemClick.
Thanks in advance!
Edit:
I'm thinking of creating a changeImage(int position, int imageId) method in my Adapter and calling that from my activity class. Is that the right approach?
In your adapter:
public void updateImage(int position, int resourceId)
{
mThumbIds[position] = resourceId;
notifyDataSetChanged();
}
In your activity:
mAdapter.updateImage(<position>, <image_resource_id>);
Notes
You will have to make the adapter a member of your activity
The main idea is that you modify the backing data and and notify the GridView that this has changed and it is time to be redrawn
Your getView() method implementation needs a lot of improvement. It will cause lots of bugs once the system starts recycling the views (the convertView parameter comes in != null for a position different than it was used for last time)
Here's a sketch of how your getView() should look like:
#Override
public View getView(int position, View convertView, ViewGroup parent)
{
ViewHolder viewHolder;
LayoutInflater inflater = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (convertView == null) {
convertView = inflater.inflate(R.layout.image, parent, false);
// next three lines would not be necessary if:
// a) it is the same for every item;
// b) you inflate properly (using the parent);
// c) you specify this in the item's xml (R.layout.image)
convertView.setLayoutParams(new GridView.LayoutParams(150, 150));
convertView.setPadding(8, 8, 8, 8);
convertView.setBackgroundResource(android.R.color.holo_red_light);
viewHolder = new ViewHolder();
viewHolder.mTextView = (TextView)convertView.findViewById(R.id.mastery_text);
viewHolder.mImageView = (ImageView)convertView.findViewById(R.id.mastery_image);
// this could also be set in xml perhaps
viewHolder.mImageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder)convertView.getTag();
}
// update the values every time we are being asked to update the item,
// because the item might have been reused from a different position
viewHolder.mImageView.setImageResource(mThumbIds[position]);
//viewHolder.mTextView.setText("myText");
return convertView;
}
public static class ViewHolder
{
TextView mTextView;
ImageView mImageView;
}
You can set a unique id to each ImageView using names (See here) or even integer numbers with a sequence or something (increasing at each image you put in the view).
Another good way to do this is using the tags, with setTag() and getTag().
This question has a good answer: What is the main purpose of setTag() getTag() methods of View?

Dynamic Grid Layout

I want to implement grid, which will be populated dynamically. I want to know what is the best approach to implement this Relative layout(List View) or Grid Layout?
You can generate a GridView dynamically.
GridView would contain of ImageView and TextView as per your need. You will have to use your custom adapter. In it's getView method, populate the ImageView and TextView.
Example:
GridView item.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<ImageView
android:id="#+id/imgItem"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:src="#drawable/ic_launcher" />
<TextView
android:id="#+id/txtItem"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:fontFamily="trebuchet"
android:textColor="#android:color/black"
android:textSize="15sp"
android:textStyle="bold" />
</LinearLayout>
Java code:
A POJO class for item:
public class Item
{
String title;
Drawable image;
//getter setter
}
Adapter class:
//getView method in your adapter class
#Override
public View getView(int position, View convertView, ViewGroup parent)
{
View itemView = convertView;
ViewHolder holder = null;
if (itemView == null)
{
final LayoutInflater layoutInflater =
(LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
itemView = layoutInflater.inflate(resourceId, parent, false);
holder = new ViewHolder();
holder.imgItem = (ImageView) itemView.findViewById(R.id.imgItem);
holder.txtItem = (TextView) itemView.findViewById(R.id.txtItem);
itemView.setTag(holder);
}
else
{
holder = (ViewHolder) itemView.getTag();
}
Item item = getItem(position);
holder.imgItem.setImageDrawable(item.getImage());
holder.txtItem.setText(item.getTitle());
return itemView;
}
Now add adapter data in your Activity class and then set that adapter to GridView.
Refer to this and this
Hope it helps.
Simply use GridView with a custom adapter. Each time you want the view to update, call notifyDataSetChanged() on the adapter.
You want GridView. Easy example here. In your case, you will need to make an XML layout for each row to accommodate both your TextView and ImageView. Other answers here address that.

ListView items drawn on top of each other when scrolling (Android)

In a fragment, I have a ListView that has a custom ParseQueryAdapter<T>. The problem may not have anything to do with Parse, although I'm not sure.
As I was testing my app, I noticed something very strange. When I would scroll down my ListView, all the visible ListView items would be drawn on top of the next ListView item as seen in the second image below.
The list initialized properly as such:
As you can see, in my list item layout, I have an ImageView (ParseImageView to be specific) and a TextView. The TextView now displays some notes (don't mind the ID user_name_text_view) and the ImageView displays a placeholder blank profile picture.
When I scrolled down, the list looked like:
Here's my list view layout named fragment_post_view_list_view:
<?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" >
<ListView
android:id="#+id/post_list_view"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</ListView>
</LinearLayout>
Here's my list item layout named list_item_post_view:
<?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="wrap_content">
<com.parse.ParseImageView
android:id="#+id/icon"
android:layout_width="75dp"
android:layout_height="75dp"
android:layout_alignParentLeft="true"
android:background="#drawable/com_facebook_profile_picture_blank_square" />
<TextView
android:id="#+id/user_name_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#+id/icon"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="#color/link_blue" />
</RelativeLayout>
Here's my adapter named PostViewListViewAdapter:
public class PostViewListViewAdapter extends ParseQueryAdapter<Post> {
// call superclass with a query to populate list view
public PostViewListViewAdapter(Context context, final String[] postsObjectIds) {
super(context, new ParseQueryAdapter.QueryFactory<Post>(){
public ParseQuery<Post> create() {
ParseQuery<Post> query = Post.getQuery();
query.whereContainedIn("objectId", Arrays.asList(postsObjectIds));
return query;
}
});
}
// this is similar to getView method in an adapter
#Override
public View getItemView(Post post, View v, ViewGroup parent) {
if(v == null) {
v = View.inflate(getContext(), R.layout.list_item_post_view, null);
}
super.getItemView(post, v, parent);
TextView usernameTextView = (TextView) v.findViewById(R.id.user_name_text_view);
usernameTextView.setText(post.getNotes()); // some string
return v;
}
}
How can I fix this problem?
Is this an issue with XML or Java?
I was following the two tutorials from Parse and the example from the Parse docs:
MealSpotting
Parse Query Adapter
I set the adapter and ListView here:
View rootView = inflater.inflate(R.layout.fragment_post_view_list_view, container, false);
mPostsObjectIds = SOME_STRING[];
PostViewListViewAdapter adapter = new PostViewListViewAdapter(getActivity(), mPostsObjectIds);
ListView listView = (ListView) rootView.findViewById(R.id.post_list_view);
listView.setAdapter(adapter);
I've tried getting rid of the ParseImageView in my list item layout, but my TextViews still draw on top of each other when I scroll.
Edit:
I forgot to mention that the list items display on top of each other after an orientation change.
I tested this on my Galaxy S5 (Android version 4.4.2 and Parse 1.4.1).
In my Activity, I show the Fragment here (called PostViewListViewFragment):
getSupportFragmentManager().beginTransaction().add(android.R.id.content, new PostViewListViewFragment()).commit();
Try below layout :
<?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:orientation="vertical" >
<ListView
android:id="#+id/post_list_view"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scrollbars="none" >
</ListView>
</RelativeLayout >
Make Sure your adapter like this:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View rowView = convertView;
// reuse views
if (rowView == null) {
LayoutInflater inflater = context.getLayoutInflater();
rowView = inflater.inflate(R.layout.rowlayout, null);
// configure view holder
ViewHolder viewHolder = new ViewHolder();
viewHolder.text = (TextView) rowView.findViewById(R.id.TextView01);
rowView.setTag(viewHolder);
}
// fill data
ViewHolder holder = (ViewHolder) rowView.getTag();
String s = names[position];
holder.text.setText(s);
return rowView;
}
}
PS:You should watch this Google IO video about Listview,and here is the slides.
First create a ViewHolder class
static class ViewHolder {
protected TextView usernameTextView;
}
Then change your getItemView method like below
public View getItemView (Post post, View convertView , ViewGroup parent)
{
ViewHolder viewHolder = null;
if (convertView == null)
{
LayoutInflater inflator = context.getLayoutInflater();
convertView = inflator.inflate(R.layout.list_item_post_view, null);
viewHolder = new ViewHolder();
viewHolder.usernameTextView = (TextView)convertView.findViewById(R.id.user_name_text_view);
convertView.setTag(viewHolder);
convertView.setTag(R.id.user_name_text_view, viewHolder.usernameTextView);
}
else
{
viewHolder = (ViewHolder) convertView.getTag();
}
viewHolder.usernameTextView.setText(post.getNotes()); // some string
return convertView;
}
The problem seems to be in your list item layout -
Change it to this -
<?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="wrap_content">
<com.parse.ParseImageView
android:id="#+id/icon"
android:layout_width="75dp"
android:layout_height="75dp"
android:layout_alignParentLeft="true" />
<TextView
android:id="#+id/user_name_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#+id/icon"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="#color/link_blue" />
</RelativeLayout>
Probably you have extra background for each list item set that is causing such effect.
Alter and watch.
Hope this gives you idea!
Try changing your list view layout height to match_parent.
Credit to #VedPrakash for helping me fix this.
In case it helps anyone, I fixed the problem by replacing the fragment not adding it. So I changed this line from:
getSupportFragmentManager().beginTransaction().add(android.R.id.content, new PostViewListViewFragment()).commit();
to:
getSupportFragmentManager().beginTransaction().replace(android.R.id.content, new PostViewListViewFragment()).commit();

ImageView over ImageView in a GridView

i am trying to use an ImageView over an ImageView in a GridView. I already found this quesiton Android, ImageView over ImageView and it is really familiar with my problem, but i want to use this Layout descripted in the question inside a GridView.
So i created a .xml-file containing the <GridView></GridView> (i think this is not really useful to show, so i skip this file) and a .xml-file with the layout i want to use in every cell in the gridview. This is the following file:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/rl_act_question_list_alternative" >
<ImageView
android:id="#+id/iv_question_list_country"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:src="#drawable/germany" />
<ImageView
android:id="#+id/iv_question_list_solved"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:src="#drawable/icon_question_solved" />
As the next step i am creating a subclass of a BaseAdapter overriding the method getView(int position, View convertView, ViewGroup parent) with the following code:
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = LayoutInflater.from(ActivityLevelsAlternative.this).inflate(R.layout.act_question_list_alternative_item, null);
}
ImageView mCountry = (ImageView) convertView.findViewById(R.id.iv_question_list_country);
ImageView mIconSolved = (ImageView) convertView.findViewById(R.id.iv_question_list_solved);
final VOQuestion question = mLevel.getAllQuestions().get(position);
mCountry.setImageResource(question.getPicture());
mIconSolved.setImageResource(mPrefManager.isQuestionSolved(question.getId()) ? R.drawable.icon_question_solved : R.drawable.icon_question_unsolved);
convertView.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
Intent i = new Intent(getApplicationContext(), ActivityQuestion.class);
i.putExtra(ActivityQuestion.QUESTION_ID, question.getId());
ActivityLevelsAlternative.this.startActivity(i);
}
});
return convertView;
}
But the the result is not the expected... see: http://q63i.img-up.net/Screenshotc656.png
My question: how can i get the check mark over the country image?
Try to change your check mark image like this:
<ImageView
android:id="#+id/iv_question_list_solved"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_alignTop="#id/iv_question_list_country"
android:layout_alignLeft="#id/iv_question_list_country"
android:layout_alignRight="#id/iv_question_list_country"
android:layout_alignBottom="#id/iv_question_list_country"/>

ImageView is still null, after findbyView

Hey im trying to get a List working, in that case i have a xml defined item, which i inflate in a extended ArrayAdapter. But after i have inflated the xml, then when i try to grab the imageview, it returns null by findviewbyid...
Here is xml for the item:
<?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="wrap_content"
android:orientation="vertical" >
<TextView
android:id="#+id/product_item_textview"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="if no image avail show this"
android:visibility="gone"/>
<ImageView
android:id="#+id/product_item_imageview"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:visibility="visible"
/>
</LinearLayout>
Method that instatiates the item:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
SimpleListItem item= items.get(position);
LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View v = vi.inflate(R.layout.product_item, null);
if(item.getPicture()!=null)
{
ImageView imgVw = (ImageView) findViewById(R.id.product_item_imageview);
String picturePath = item.getPicture();
Bitmap picture = ImageManager.get(getBaseContext(), picturePath);
imgVw.setImageBitmap(picture);
} else {
TextView txtVw = (TextView) findViewById(R.id.product_item_textview);
txtVw.setText(item.getText());
txtVw.setVisibility(View.VISIBLE);
}
return v;
}
Its a,
ImageView imgVw = (ImageView) v.findViewById(R.id.product_item_imageview);
also the same for TextView,
TextView txtVw = (TextView) v.findViewById(R.id.product_item_textview);
Use View v for getting ImageView and TextView from your inflated xml file.
//you are inflating layout in a view v so you need to get them by
ImageView imgVw = (ImageView)v. findViewById(R.id.product_item_imageview);
TextView txtVw = (TextView)v. findViewById(R.id.product_item_textview);

Categories

Resources