I am working on a sample application in which I need to get the resource of an image view in a onClick listener and compare that with the image source that I know exists. If the resources are the same, I want to launch another intent. The problem I am facing right now is to access that ImageView (and hence its resource Id integer) to compare to the drawable resource.
#Override
// should int be final ??
public View getView(final int position, View convertView, ViewGroup parent) {
ImageView imageView;
if (convertView == null) { // if it's not recycled, initialize some attributes
imageView = new ImageView(mContext);
imageView.setLayoutParams(new GridView.LayoutParams(85, 85));
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setPadding(8, 8, 8, 8);
} else {
imageView = (ImageView) convertView;
}
imageView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// This is not working and I need to find a way to solve this >>
if (((ImageView)v).getResources().getInteger(0) == R.drawable.imageToCompare)
{
// do nothing
}
else
{
// do something
}
You can't get a drawable id from an ImageView. But if you set it from code, you can also store it somewhere, for example in the tag field. Take a look at the similar question: Who I compare an background Image resource TextView with a R.drawable.bg_image for switch.
if(((ImageView)v).getDrawable().getConstantState() == MainActivity.this
.getResources().getDrawable(R.drawable.unlock)
.getConstantState()))
{
// Do Something
}
The proper way is to user setTag() and getTag. I guess you are making your own adapter.
In the method public View getView(int position, View convertView, ViewGroup parent), you set tag to Imageview when you add other properties to it.
ImageView temp = (ImageView) v.findViewById(resId);
temp.setImageResource(icon);
temp.setTag(icon); //drawable unique ID will be my identifier here
Then in the onClick you simply compare View v with your drawable id. For example, I wanted to change image on click and I coded it this way. Take notice how I also change tag when I set a new drawable
img.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
if ((Integer)v.getTag() == R.drawable.current_img) {
v.setBackgroundResource(R.drawable.new_img);
v.setTag(R.drawable.new_img);
}
}
});
You can use this.
if((pic1.getDrawable().getConstantState() == getResources().getDrawable(R.drawable.addpics).getConstantState()))
{
//do something
}
Related
I have a custom listview, each item have a imagebutton, i want to change image of each imagebutton immediately when I click. Each item in custom listview is a object named baiHat{}.
I use BaiHatAdapter like this, but it not chane immediately, i must scroll listview to see change.
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater=this.context.getLayoutInflater();
View row=inflater.inflate(this.resource, null);
TextView txtMs = (TextView) row.findViewById(R.id.ms);
TextView txtBh = (TextView) row.findViewById(R.id.bh);
TextView txtCs = (TextView) row.findViewById(R.id.cs);
TextView txtLr = (TextView) row.findViewById(R.id.lr);
ImageButton imglike = (ImageButton) row.findViewById(R.id.imageButton);
final BaiHat baiHat = this.objects.get(position);
txtMs.setText(baiHat.getTxtms());
txtBh.setText(baiHat.getTenBh());
txtCs.setText(baiHat.getTxtcs());
txtLr.setText(baiHat.getTxtLr());
imglike.setImageResource(baiHat.getImg());
imglike.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
xulythich(baiHat);
}
});
return row;
}
private void xulythich(BaiHat baiHat) {
if(baiHat.getThich()){
baiHat.setThich(false);
baiHat.setImg(R.drawable.addfav);
}else{
baiHat.setThich(true);
baiHat.setImg(R.drawable.added);
}
}
Create a selector file and assigning it as src would work. But as a better approach you can try to change it to togglebutton, since imageview is not meant to be clickable and give it the background of selector source.
It will just look like any imageview but with the capability of being clickable and changing its background from the selector file.
I am following a tutorial here - Now instead of adding a textView I have the following method as a replacement:
public void addView(LinearLayout container, String[] spin_array, String hint, int inputType, int tagger) {
LayoutInflater layoutInflater = (LayoutInflater) getActivity().getBaseContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
final View addView = layoutInflater.inflate(R.layout.add_company_fragment_two_dynamic_content, null);
final Spinner spin_dynamic = (Spinner) addView.findViewById(R.id.email_spinner1);
EditText edt_dynamic = (EditText) addView.findViewById(R.id.edittext_email1);
ImageView remove_dynamic = (ImageView) addView.findViewById(R.id.btn_remove);
edt_dynamic.setHint(hint);
setUpSpinners(spin_array, spin_dynamic);
edt_dynamic.setTag(container.getTag() + "edt" + tagger);
edt_dynamic.setInputType(inputType);
edt_dynamic.setTypeface(roboto_condenced_light);
spin_dynamic.setTag(container.getTag() + "spin" + tagger);
idsMap.put(spin_dynamic.getTag().toString(), edt_dynamic.getTag().toString());
// get height from dimens
int height = (int) getResources().getDimension(R.dimen.lin_height);
// set this height
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, height);
// we are only concerned about top margin here.
layoutParams.setMargins(0, (int) getResources().getDimension(R.dimen.topMargin), 0, 0);
container.addView(addView, 1, layoutParams);
remove_dynamic.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//Remove View (LinearLayout) and also remove the key from idsMap so that we dont get a NullPointer later
((LinearLayout) addView.getParent()).removeView(addView);
idsMap.remove(spin_dynamic.getTag().toString());
}
});
}
The concern here is that I can call the above function umpteen times, to insert a view row in a LinearLayout.
I fail to understand how the addView variable is kept track of, when we try to remove a view from the container:
remove_dynamic.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//Remove View (LinearLayout) and also remove the key from idsMap so that we dont get a NullPointer later
((LinearLayout) addView.getParent()).removeView(addView);
idsMap.remove(spin_dynamic.getTag().toString());
}
});
How does the onClickListener know the addView instance to be removed here, if I insert four views how does teh onClick exactly know which one to remove?
There are no errors, everything is working as it should. But why is it working?
Following is an image representing this behavior:
you have to use the same viewobject while removing view for example you have added three view in ViewGroup
addView1
addView2
addView3
so when you want to remove fistview i.e. addView1 you have to use that object ((LinearLayout) addView.getParent()).removeView(addView1);
It's working due to this line
((LinearLayout) addView.getParent()).removeView(addView);
onClickListener() does not keep track of anything.
I'm trying to fix an issues that I've seen previously and fixed on iOS, but am unable to fix on android. In iOS, I used the SDWebImage library to download and cache images. However, when scrolling through a long list of cells, the images would come up in the wrong cells. I was able ot fix this by doing the following:
#property (weak) id <SDWebImageOperation> imageOperation;
...
- (void)setFriend:(TAGUser *)friend {
...
self.imageOperation = [[SDWebImageManager sharedManager] downloadWithURL:[NSURL URLWithString:friend.profileImageUrl] options:SDWebImageRetryFailed
progress:^(NSInteger receivedSize, NSInteger expectedSize) {
} completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished) {
if(!error) {
self.profileImageView.image = image;
}
}];
...
}
- (void)prepareForReuse {
[super prepareForReuse];
if (self.imageOperation) {
[self.imageOperation cancel];
}
self.imageOperation = nil;
}
On Android, I am using the Picaso Libray and trying to achieve the same result like so:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View vi = convertView;
if (vi == null) {
vi = inflater.inflate(R.layout.friend_row, parent, false);
ViewHolder holder = new ViewHolder();
holder.friendImage = (ImageView) vi.findViewById(R.id.friend_image);
}
final ViewHolder holder = (ViewHolder) vi.getTag(); //Bad naming convention in my project I know, but it's a built-in method
//THIS SHOULD IN THEORY CANCEL THE REQUEST OF THE OLD FRIEND URL
Picasso.with(mActivity.getBaseContext()).cancelRequest(holder.friendImage);
holder.friendImage.setImageDrawable(mActivity.getResources().getDrawable(R.drawable.background_circle));
final TagUser user = (TagUser) getItem(position);
Picasso.with(mActivity.getBaseContext()).load(user.getProfileUrl()).transform(new RoundedTransformation(ViewUtility.convertPxToDp(mActivity, 23), 0)).fit().into(holder.friendImage,
new Callback() {
#Override
public void onSuccess() {
holder.friendInitials.setVisibility(View.INVISIBLE);
}
#Override
public void onError() {
holder.friendInitials.setVisibility(View.VISIBLE);
}
});
}
Even with cancelRequeset getting called, the profile images are still getting mismatched. Any help would be greatly appreciated!
You don't need to call cancel. Picasso automatically sees when views are being re-used and will cancel old downloads for that image view.
I would also recommend using Picasso's .placeholder API for the background circle.
You seem to be missing a call to setTag when the layout is inflated. Hopefully that's just an error in copying to the post.
Lastly, create the RoundedTransformation once and re-use the same instance for all calls to Picasso.
In the end your code should look like this:
private final Transformation roundTransform;
// Set the following in constructor:
// roundTransform = new RoundedTransformation(ViewUtility.convertPxToDp(mActivity, 23), 0)
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View vi = convertView;
if (vi == null) {
vi = inflater.inflate(R.layout.friend_row, parent, false);
ViewHolder holder = new ViewHolder();
vi.setTag(holder)
holder.friendImage = (ImageView) vi.findViewById(R.id.friend_image);
}
final ViewHolder holder = (ViewHolder) vi.getTag(); //Bad naming convention in my project I know, but it's a built-in method
final TagUser user = (TagUser) getItem(position);
Picasso.with(mActivity)
.load(user.getProfileUrl())
.placeholder(R.drawable.background_circle)
.transform(roundTransform)
.fit()
.into(holder.friendImage,
new Callback() {
#Override
public void onSuccess() {
holder.friendInitials.setVisibility(View.INVISIBLE);
}
#Override
public void onError() {
holder.friendInitials.setVisibility(View.VISIBLE);
}
});
}
I would advice to use Volley by Google. I have used it in many projects and it never gave mismatched results even in case I had nearly 1000 images in 3 column gridView. Volley
I am trying to make an app similar to the Logo quiz's, but in stead of guessing the logos, you get to see a part of a car and you have to guess which car it is. I have listed the car pictures in a gridview and when you click it you can enter your answer. This all works fine. When you have given the correct answer, this is saved to an SQLite database. So now my question is: How can i show a tick mark or green outline etc. in the gridview, only at the pictures you have answered correctly? If a picture has been answered correctly already, a string with "YES" is inserted under the column "Correct" in the database. Here is what i have so far:
private void checkDB() {
try{
DbHelper entry = new DbHelper (Main.this);
entry.openDataBase();
Cursor c = entry.getInfo();
//Check everything at the "Correct" column
for (c.moveToFirst(); !c.isAfterLast(); c.moveToNext()){
String correct = c.getString(1);
if (correct.equals("YES")){
//If it has been answered correctly get it's id
int id = c.getInt(0);
//Add the tick mark at the specific picture
gridView.?????
}
else{
}
entry.close();
}
}
catch(Exception e){
}
}
I am really unexperienced at programming, so i hope you understand what i mean ;) Please help!
I can get the position of the clicked image by making the position final and adding an onClick listener to the imageView.
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
ImageView imageView;
if (convertView == null) {
// if it's not recycled, initialize some attributes
imageView = new ImageView(mContext);
imageView.setLayoutParams(new GridView.LayoutParams(80, 80));
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setPadding(10, 8, 10, 8);
imageView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Log.d("onClick","position ["+position+"]");
}
});
}
else
{
imageView = (ImageView) convertView;
}
imageView.setImageResource(mThumbIds[position]);
return imageView;
}
I have images displayed in a GridView as in this tutorial. I want to be able to click on a single image and do other events and I need to know what image was clicked.
Do I have to add imageView.onKeyDown(keyCode, event) in the ImageAdapter class? Here is the code as it currently exists:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView;
if (convertView == null) {
// if it's not recycled, initialize some attributes
imageView = new ImageView(mContext);
imageView.setLayoutParams(new GridView.LayoutParams(85, 85));
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setPadding(8, 8, 8, 8);
//does this need imageView.onKeyDown(keyCode, event)?
}
else {
imageView = (ImageView) convertView;
}
imageView.setImageResource(mThumbIds[position]);
return imageView;
}
How will it indicate what image was clicked? How do I create the proper handler?
For a GridView you can use the setOnItemClickListener method to have an OnItemClickListener listener. That listener will give you a method that you must override with the signature
onItemClick(AdapterView<?> parent, View v, int position, long id)
where you get the position of the item in the grid that was clicked and the View that is inside the cell of the grid. Is that what you need?
I was able to get the position of the clicked image by making the position final and adding an onClick listener to the imageView. This logs the position of the image that was clicked.
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
ImageView imageView;
if (convertView == null) {
// if it's not recycled, initialize some attributes
imageView = new ImageView(mContext);
imageView.setLayoutParams(new GridView.LayoutParams(85, 85));
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setPadding(8, 8, 8, 8);
imageView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Log.d("onClick","position ["+position+"]");
}
});
}
else {
imageView = (ImageView) convertView;
}
imageView.setImageResource(mThumbIds[position]);
return imageView;
}
i tried the above mentioned method getView(final int position . . .)
realized that the position got "reset" after 28 items and the position when back to 0 after the 28th item in the gridview.
i suspected the final keyword is creating problem and after removing it i was able to get the positions as expected.
Below is a sample code with the click event being called in the activity that is showcasing the gridview.
public class MainActivity extends Activity {
ArrayList<Integer> item_ids = new ArrayList<Integer>();
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
item_ids = //get your item ids method
GridView gridview = (GridView) findViewById(R.id.grid_featured);
gridview.setAdapter(new ImageAdapter(this));
gridview.setOnItemClickListener(itemClickListener);
footer = (Footer)findViewById(R.id.layoutFooter);
footer.setActivity(this);
}
private OnItemClickListener itemClickListener = new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
Log.d(TAG,"Position Clicked ["+position+"] with item id ["+item_ids.get(position)+"]");
}
};
}