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.
Related
I have created a horizontal recyclerview list. below is the image I have attached.
problem is that I have to change bulb state when everytime user clicked that row from off state to on state and on state to off state.
How do I implement this logic? please help me to find out the solution.
i want to change light color according to user clicks, if he clicks on then it should change its color for that row and vise versa
public void onClick(View view, int position) {
//toast("clicked" + position );
if (!lightClicked){
ImageView lightPopUp = view.findViewById(R.id.row_light_thumbnail);
DrawableCompat.setTint(lightPopUp.getDrawable().mutate(), ContextCompat.getColor(getContext(), R.color.white));
//toast("light on");
lightClicked = true;
}else {
ImageView lightPopUp = view.findViewById(R.id.row_light_thumbnail);
//toast("light off");
DrawableCompat.setTint(lightPopUp.getDrawable().mutate(), ContextCompat.getColor(getContext(), R.color.colorAccent));
lightClicked = false;
}
//View view1 = mLayoutManager.findViewByPosition(position);
}
Dont directly do this change as the recycler view's cells are reused and it wont work as expected, so instead apply the change in the list you are using. You can add a boolean variable in the model class of the list you use to populate the recycler view, and than on its click you can change the boolean's value and call notifydatasetchange on the adapter, and in bind view you should keep an If else condition based on that boolean for the Bulb's image
ie. if true set one image if false set another
declare this :
int selectedPosition=-1;
inside onBindViewHolder:
public void onBindViewHolder(FiltersAdapter.ViewHolder holder, int position) {
if(selectedPosition==position)
holder.itemView.setImageResource(R.drawable.higlihgt_image);
else
holder.itemView.setImageResource(R.drawable.normal_image);
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
selectedPosition=position;
notifyDataSetChanged();
}
});
}
I am creating a program that has the mainMenuButton button (created in onCreate) disabled by default.
The user first has to check a few boxes and select something from the spinner before the mainMenuButton button becomes enabled. Currently, I can't even get the button to enable after using the spinner.
I've tried both
#Override
public void onClick(View v)
{
switch(v.getId())
{
case R.id.main_menu_button:
openMainMenu();
break;
case R.id.building_spinner:
Button mainMenuButton=(Button)findViewById(R.id.main_menu_button);
mainMenuButton.setEnabled(true);
break;
}
}
and
public void onItemSelected(AdapterView<?> parent, View view, int position, long id)
{
View mainMenuButton=(View)findViewById(R.id.main_menu_button);
mainMenuButton.setEnabled(true);
}
but to no avail. I've also tried replacing View with Button, but that didn't enable the mainMenuButton either. What exactly am I supposed to do to enable the button after something on the spinner has been selected?
Also, would there be much of a big difference to implement it for checkboxes as well?
EDIT2 :
If I comment out the if and else statement, the button remains permanently disabled. If I leave as is, the button is never disabled to begin with and never disables, which I don't understand because I haven't even touched the spinner, so it should be disabled by default.
public void onItemSelected(AdapterView<?> parent, View view, int position, long id)
{
String buildingString = parent.getItemAtPosition(position).toString();
if(buildingString !="Select Building")
{
Button mainMenuButton=(Button)findViewById(R.id.main_menu_button);
mainMenuButton.setEnabled(true);
}
else
{
Button mainMenuButton=(Button)findViewById(R.id.main_menu_button);
mainMenuButton.setEnabled(false);
}
}
Im not sure if this affects it, but the spinner strings was formatted like this :
<string-array name="building_array">
<item>Select Building</item>
You've not registered a listener on spinner.
Add this in your onCreate
spinner.setOnItemSelectedListener(this);
and then write you code in onItemSelected.
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!
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;
}
I'm using a grid view to display a month calendar. When i touch a date on the calendar , the corresponding cell is highlighted by changing its background and text Color. Everything works like charm except the fact that i can't un-highlight a cell if i choose a new date.
When i click a date i remember the position, so when i chose a new one i know where i clicked previously :
protected OnClickListener onClicThisMonthDate(final int position)
{
return new OnClickListener() {
#Override
public void onClick(View v)
{
if(prevDateSelected > -1 )
{
//Get the view by the oldPosition
//Change its background and text color
}
prevDateSelected = position;
TextView casecal = (TextView) v.findViewById(R.id.case_cal);
casecal.setBackgroundColor(Color.rgb(93, 94, 94));
casecal.setTextColor(Color.WHITE);
}
};
}
Is there a solution to get a view by his position ? What's the most efficient way to select a cell and unselect all the other ?
Note : By "select a cell" i mean highlight it, by changing it style.
ViewGroup.getChildAt returns the view at the specified position in the group.
GridView.setSelection selects of the view at the position and unselects others views.