What I've done:
Hello Guys,
I've got a GrindView which i filled over my Database. Now the Images shows up there and are scrollable. But when I click on it, they don't keep selected. To see which picture is selected I builded a Toastmessage which shows me what picture i clicked on with the onIemClickListner.
Question:
I'd like to let the Clicked Image, selected. So that you click on time on a Image in the GridView and afterwards it keeps selected.
How can i realize that? I would be happy if there's a tutorial or a codesample, to see how it works.
The Code
This is what i tried that only the actual image gets keeps selected with the colors but it dosn't work the right way, sometimes it just changes..
//Hier wird gemerkt welches bild
gridview.setOnItemClickListener(new OnItemClickListener() {
boolean color = false;
View old;
View v;
public void onItemClick(AdapterView<?> parent, View vv, int position, long id) {
Toast.makeText(SFilterConfigActivity.this, "" + position, Toast.LENGTH_SHORT).show();
v = vv;
//gridview.setSelection(position);
if (color == false){
v.setBackgroundColor(0xFF00FF00);
old = v;
color = true;
}
else {
old.setBackgroundColor(0x00000000);
v.setBackgroundColor(0xFF00FF00);
color = false;
}
}
});
Thx for you anwser in advance
safari
After you call setAdapter()
do it like this
setSelection(setSelected, true)
Following is the working code.
if (color == false){
vv.setBackgroundColor(getResources().getColor(R.color.green));
old = vv;
color = true;
} else {
old.setBackgroundColor(getResources().getColor(R.color.white));
vv.setBackgroundColor(getResources().getColor(R.color.green));
old=vv;
}
Related
I am developing a music playing app but I've been stuck with fixing a bug for the last two days. Here is a screenshot of the app. Basically the user can add a new view, name it however he wishes and choose a mp3 file to link to that view.
As you can see Every view has a text that a little play icon. This icon switches to a pause icon while the audio is playing. Here you can see the pause icon.
Issue 1:
When the user starts a sound and then click on another square, the previous sound stops as it should and the new sound begins, but the old square's icon stays the pause icon, and so on the screen eventally many squares will have the pause icon while not actually playing sound.
Issue 2: Let's say that the user clicks the absolute first square, which in the arrayList corresponds to position 0. Then the user scrolls down to the point that the square he clicked is no longer visible. When the user scrolls up again the square he clicked on will have the play icon set, while playing sound. I figured that's because in my GridAdapter i set every newly recicled view to have the play icon and I can't figure out how to set an if statement. How should the adapter know wether the box is playing a sound?
Many thanks and love.
GridItemAdapter.java:
public class GridItemAdapter extends ArrayAdapter<GridItem> {
private static final String LOG_TAG = GridItemAdapter.class.getSimpleName();
public GridItemAdapter(Activity context, ArrayList<GridItem> gridItems) {
// Here, we initialize the ArrayAdapter's internal storage for the context and the list.
// the second argument is used when the ArrayAdapter is populating a single TextView.
// Because this is a custom adapter for two TextViews and an ImageView, the adapter is not
// going to use this second argument, so it can be any value. Here, we used 0.
super(context, 0, gridItems);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// Check if the existing view is being reused, otherwise inflate the view
View gridItemView = convertView;
if(gridItemView == null) {
gridItemView = LayoutInflater.from(getContext()).inflate(
R.layout.grid_item, parent, false);
}
// Get the {#link AndroidFlavor} object located at this position in the list
GridItem currentGridItem = getItem(position);
// Find the TextView in the list_item.xml layout with the ID version_name
TextView nameTextView = (TextView) gridItemView.findViewById(R.id.text_1);
// set this text on the name TextView
nameTextView.setText(currentGridItem.getSoundName());
ImageView playIcon = (ImageView) gridItemView.findViewById(R.id.image_1);
playIcon.setImageResource(R.drawable.play_ic);
// Return the whole list item layout (containing 2 TextViews and an ImageView)
// so that it can be shown in the ListView
return gridItemView;
}
}
MainActivity.java snippets of interest :
gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
/*
if (lastPosition != -1) {
Log.v(TAG3, "Inisde if block, lastposition = " + lastPosition);
// Whatever position you're looking for
int firstPosition = gridView.getFirstVisiblePosition();
int wantedChild = lastPosition - firstPosition;
View wantedView = gridView.getChildAt(wantedChild);
Log.v(TAG3, "lastRow initiated, lastrow = " + wantedView);
ImageView lastIc = (ImageView) wantedView.findViewById(R.id.image_1);
lastIc.setImageResource(R.drawable.play_ic);
}
*/
togglePlayback(i, view);
lastPosition = i;
Log.v(TAG3, "outside if block, lastPosition = " + lastPosition);
}
});
public void togglePlayback(int i, View v){
final View view = v;
if(!isPlaying) {
releaseMediaPlayer();
ImageView playIc = (ImageView) view.findViewById(R.id.image_1);
playIc.setImageResource(R.drawable.pause_ic);
GridItem word = gridItems.get(i);
try {
mMediaPlayer = MediaPlayer.create(MainActivity.this, Uri.parse(word.getSoundPath()));
}catch (IllegalArgumentException e){
e.printStackTrace();
}
mMediaPlayer.start();
isPlaying = true;
mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mediaPlayer) {
releaseMediaPlayer();
ImageView playIc = (ImageView) view.findViewById(R.id.image_1);
playIc.setImageResource(R.drawable.play_ic);
isPlaying = false;
}
});
}else{
releaseMediaPlayer();
ImageView playIc = (ImageView) view.findViewById(R.id.image_1);
playIc.setImageResource(R.drawable.play_ic);
isPlaying = false;
}
}
Here is a simple way to achieve it(I have not gone through your code since the snippet was not provided yet, the variables used below are self-explanatory):
First add a flag say isPlaying in the model class of an item in gridview
Now in getView method, add below code
if(itemList.get(index).isPlaying) {
//set the icon to pause one
} else {
//set the icon to playing one
}
Now, in view's click listener, add this
if(itemList.get(index).isPlaying) {
// write the code to pause the current song
} else {
// pause your <previousIndex> song
// play <index> item
itemList.get(index).isPlaying = true;
itemList.get(previousIndex).isPlaying = false;
previousIndex = index;
notifyDataSetChanged();
}
I have just written the basic logic, you need to write your code regarding playing/pause of your songs.
Hope this helps you.
I'm using this code
ListView lv = getListView();
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
TextView idno = (TextView) view.findViewById(R.id.idno);
TextView fullname = (TextView) view.findViewById(R.id.fullname);
TextView remark = (TextView) view.findViewById(R.id.remark);
new DisplayStudent().execute("Update", idno.getText().toString());
if(remark.getText().toString().equals("absent")) {
if(isStudentLate) {
view.setBackgroundColor(ContextCompat.getColor(getApplicationContext(), R.color.colorLate));
fullname.setTextColor(Color.WHITE);
remark.setText("late");
}
else {
view.setBackgroundColor(ContextCompat.getColor(getApplicationContext(), R.color.colorPresent));
fullname.setTextColor(Color.WHITE);
remark.setText("present");
}
}
else if(remark.getText().toString().equals("present") || remark.getText().toString().equals("late")) {
view.setBackgroundColor(Color.WHITE);
fullname.setTextColor(Color.BLACK);
remark.setText("absent");
}
}
});
((BaseAdapter)getListView().getAdapter()).notifyDataSetChanged();
Everytime I tap on an item, the background color of the item I tapped is supposed to change. Why does it not change? I tried removing the ((BaseAdapter)getListView().getAdapter()).notifyDataSetChanged(); it does change but when I scroll down and scroll up again it goes back to its original background color.
For example. One Item's background color is colored white. When I tap that item, it changed to green. That's perfect. But when I scroll down and scroll up again, the item that I tapped changed back to white. How do I fix this?
Try setting this in your ListView tag:
android:cacheColorHint="#00000000"
And also try this:
android:background="color code here"
Basically I was trying to change the Image on the group click and its not successful.
I am able to receive correct logs for group expanded and collapsed but the ImageView is not updating according to that.
Here's a sample code for it and I am not sure what's wrong with it:
private android.widget.ExpandableListView.OnGroupClickListener mGroupClickListener= new OnGroupClickListener() {
#Override
public boolean onGroupClick(ExpandableListView parent, View v, int groupPosition, long id) {
Bitmap mBitmapCollapsed = BitmapFactory.decodeResource(getActivity().getResources(), R.drawable.ic_launcher);
Bitmap mBitmapExpanded = BitmapFactory.decodeResource(getActivity().getResources(), R.drawable.ic_drawer);
ImageView mImageView = (ImageView)v.findViewById(R.id.carat_imageView);
if (parent.isGroupExpanded(groupPosition)) {
parent.collapseGroup(groupPosition);
Log.d("onGroupClick:", "groupCollapsed");
mImageView.setImageBitmap(mBitmapCollapsed);
} else {
parent.expandGroup(groupPosition);
Log.d("onGroupClick:", "groupExpanded");
mImageView.setImageBitmap(mBitmapExpanded);
}
return false;
}
};
I am not able to determine the problem here and it seems like the code is fine.
A little help will be really appreciated. Thanks in advance.. :)
Found a solution actually:
onGroupView:
I set the id as :
//isExpanded is a boolean in the onGroupView method
(!isExpanded) ? R.drawable.closed_icon: R.drawable.expanded_icon;
and set the ImageView as :
mImageView.setImageResource(id);
Hope this helps someone..:)
I want to draw a check mark for the image view I click on and uncheck the imageview I clicked on before using the following code snip. I store last checked position in mDeviceAdapter. When I try to uncheck old position, the image view always gives null even for the partial visible image view. I am really confused because I thought only invisible one is recycled... Newbie in Android and any comment is appreciated.
public void CheckableImageView#setChecked(boolean checked) {
if (mChecked != checked) {
mChecked = checked;
invalidate();
}
}
mDeviceGallery.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
CheckableImageView viewToCheck = (CheckableImageView) view;
if (!viewToCheck.isChecked()) {
int oldCheckedPosition = mDeviceAdapter
.getCheckedPosition();
mDeviceAdapter.setCheckedPosition(position);
View checkedView = mDeviceGallery
.getChildAt(oldCheckedPosition);
Log.d(TAG, "old position="+oldCheckedPosition + "old view="+checkedView);
if (checkedView != null) {
((CheckableImageView) checkedView)
.setChecked(false);
Log.d(TAG, "uncheck position="
+ oldCheckedPosition);
}
viewToCheck.setChecked(true);
That's not the right approach.
You need to add to your data type a boolean field (i.e mIsChecked).
On the onItemClick method set the value of that variable to true and keep its INDEX as a member of the adapter. When another item is clicked set the value of that item to true and set the value of the saved one to false (change the value of the datatype in you ArrayList in the INDEX you stored in the previous click).
Now, in the getView() method, you must have if/else statement. Something like:
if (item.isChecked())
{
checkedView.setChecked(true);
}
else
{
checkedView.setChecked(false);
}
Example to the onClick method: (just a general direction)
if (item.isChecked())
{
checkedView.setChecked(false);
yourList.get(position).setChecked(true);
yourList.get(mLastCheckedIndex).setChecked(false);
mLastCheckedIndex = position;
notifyDataSetChanged();
}
else
{
//same but opposite.
}
Hope this helps!
I have created custom View called Color. I use object of Color to fill GridView (same issue is in ListView also).
My task is to let user choose one color and highlight it.
Previously I do something like that but I used only in building widgets and everything worked. This time I use my own.
This cose is for item clicking:
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
int color = (int)id;
Log.d(TAG, "Selected color: " + id);
view.setSelected(true);
view.invalidate();
}
Color.onDraw:
#Override
public void onDraw(Canvas canvas) {
if (isSelected()) {
Log.d(TAG, "color draw selected");
} else {
Log.d(TAG, "not selected " + color);
}
}
Also I set setChoiceMode(AbsListView.CHOICE_MODE_SINGLE); to this GridView (AbsListView.CHOICE_MODE_MULTIPLE don't help also)
In log I see:
Selected color: 8355711
not selected 16711680
not selected 16743680
not selected 8355711
I am sure, Color items is not recreating more than on time.
I tried change GridView to ListView, user default widget (overrided only onDraw()). Nothing helps. Maybe I forgot something?
In my opinion GridView somehow drop selected status.
If you need more info just tell.
Addition:
I checked with debugger. View with color 8355711 is same object in both functions.
I used setOnItemSelectedListener(this); to track item selection. But nothing happen in this listener.
The method isSelected() is comming from the GridView which is a child of View.
Basically when calling isSelected() you're saying: "is the gridview selected" which is not what you want.
What you want is: "is there any selected view in the grid view ?"
Which could be achieved using getSelectedView()
As the documentation says, you will get a reference to the selected view or null if none is selected.
Also make sur your GridView is properly initialized to handle item selection.
EDIT : Ok i understand that isSelected() is called from the Color view. My first guess is then useless.
But I think you should try to make your item selected using the setSelection() of the GridView object.
Add something like:
myGridView.setSelection(position);
I fix this issue my self by making my own select. Its workaround.
In Color class added:
private boolean selected = false;
public boolean isSelected2() {
return selected;
}
public void setSelected2(boolean selected) {
this.selected = selected;
}
#Override
public void onDraw(Canvas canvas) {
....
if (isSelected2()) {
//draw selected state
} else {
....
}
On ColorChooser grid:
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
...
int i = getChildCount();
while (--i >= 0)
((Color)getChildAt(i)).setSelected2(false);
((Color)view).setSelected2(true);
....
}
Reason why I not to override natice setSelected(boolean state) is some other code in grid every time make all items in deselected state. I don't know why, because in other places same more native code work very fine.