I'm trying to display a RatingBar View that is only capable of showing a one star rating, or no stars. This seems so trivial...
My ratingbar is defined like so:
My view implements OnRatingBarChangeListener and OnTouchListener
My OnRatingBarChange handler has no code.
My OnTouch handler looks like so:
#Override
public boolean onTouch(View v, MotionEvent event)
{
if(event.getAction() == MotionEvent.ACTION_DOWN)
{
if(this.mRating.getRating() == 0)
{
this.mRating.setRating(1);
}
else
{
this.mRating.setRating(0);
}
return true;
}
return false;
}
No matter what, the onTouch event does not succeed at setting the rating back to zero. This seems way too trivial. What am I doing wrong?
Thanks!
Consider using ToggleButton and btn_star stock drawable instead. Here's example:
<ToggleButton
android:button="#android:drawable/btn_star"
android:background="#android:color/transparent"
android:textOn=""
android:textOff=""
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
The RatingBar is extended from the SeekBar and the listener actually expects a slide action. Thus the RB can't be set to 0 (or not for this purpose) when there is only one star. The proper widget to use for this type of functionality (no surprise here) is the ToggleButton.
I had the same problem, trying to use a single star RatingBar as a favourite button. But the ToggleButton is exactly what you need for this type of thing.
This is what I implemented for the ToggleButton. (The _favourited bool was specifically used for something in my code, I can't remember now)
favourite_button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (!_favourited) {
// Do stuff
_favourited = true;
} else {
// Do stuff
_favourited = false;
}
}});
Related
I have a button and I want to give it %20 opacity. After click it has to be in old color without an opacity or transparency.
This is my XML:
<com.example.android.custombutton.CustomButton
android:id="#+id/custombutton_cardselection_turkish_id"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:backgroundTint="#color/blue_button"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:layout_marginBottom="16dp"
android:text="#string/nfc_new_turkish_id"
android:textColor="#color/white"
app:layout_constraintBottom_toTopOf="#+id/custombutton_cardselection_passport"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/guideline_cardselection_top" />
I want to change it in XML not in the kotlin part. How can I do that?
You can use OnTouchListener to achieve the hover effect as you were asking.
However, you can't achieve this using XML instead you need to do this programmatically.
for java use this
yourBtn.onTouchEvent(new View.OnTouchListener(){
#Override
public boolean onTouch(View v, MotionEvent event) {
yourBtn.getBackground().setAlpha(1);
yourBtn.setBackgroundColor("#ffffff");
if (event.getAction() == MotionEvent.ACTION_UP) {
yourBtn.getBackground().setAlpha((float) 0.2);
}
return false;
}
});
for kotlin use this
yourBtn.onTouchEvent(object:View.OnTouchListener() {
fun onTouch(v:View, event:MotionEvent):Boolean {
yourBtn.getBackground().setAlpha(1)
yourBtn.setBackgroundColor("#ffffff")
if (event.getAction() === MotionEvent.ACTION_UP)
{
yourBtn.getBackground().setAlpha(0.2.toFloat())
}
return false
}
})
if the user clicks your button (I mean touches your button) then it will become opaque and you can set the background color as you want and then if the user lifts up his finger then it will become 20% transparent.
use this code
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
btn.getBackground().setAlpha(0);
}
});
you can also set android:background="#10FF0000" in xml file
I have a list of items disposed vertically. Each item has a CheckBox and a TextView.
I'm trying to achieve a LongClick behavior for the CheckBox. More precisely i want it to change it with a trash icon while is LongClicked. On release it must become again a checkBox and also maintain the Check/Uncheck behavior on simple click.
How can i achieve that? How many approaches are there?
I apriciate any king of help!
I tried to just use setBackgroud() function, but it would just draw under the existing checkbox view, with the box still remaining on the top.
cb.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
Resources res = tmp_context.getResources();
Drawable drawable = res.getDrawable(R.mipmap.ic_trash);
cb.setBackground(drawable);
return false;
}
});
UPDATE
First Put your chekcbox inside a framelayout :
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/one"
android:id="#+id/fl">
<CheckBox
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Two"
android:longClickable="true"
android:id="#+id/two"/>
</FrameLayout>
you could use LongClickListener and OnTouchListener:
private View.OnLongClickListener pressHoldListener = new View.OnLongClickListener() {
#Override
public boolean onLongClick(View pView) {
// Do something when your hold starts here.
isSpeakButtonLongPressed = true;
mFrameLayout.setBackgroundResource(R.drawable.trash_can);
yourCheckBox.setVisibility(VIEW.INVISIBLE);
return true;
}
};
private View.OnTouchListener pressTouchListener = new View.OnTouchListener() {
#Override
public boolean onTouch(View pView, MotionEvent pEvent) {
pView.onTouchEvent(pEvent);
// We're only interested in when the button is released.
if (pEvent.getAction() == MotionEvent.ACTION_UP) {
// We're only interested in anything if our speak button is currently pressed.
if (isSpeakButtonLongPressed) {
// Do something when the button is released.
yourCheckBox.setVisibility(View.VISIBLE);
mFrameLayout.setBackground(null);
isSpeakButtonLongPressed = false;
}
}
return false;
}
};
Inside you onCreate() :
yourCheckBox.setOnLongClickListener(pressHoldListener);
yourCheckBox.setOnTouchListener(pressTouchListener);
Also add
android:longClickable="true"
to your checkbox xml.
This is so strange, but if you put an onClickListener on a TextView (or non-editable EditText) which has android:textIsSelectable="true" - it needs not one tap, but two.
I checked it on 3 phones and all of them perform onClick only after second tap.
Of course, if you make focusable="false" or android:textIsSelectable="false" it works from the 1st tap, but text selection doesn't work.
Please, help me with that issue
Set in XML to your TextView:
android:textIsSelectable="true"
After that set onTouchListener to your TextView and in them do this:
if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) view.requestFocus();
It's set focus for every tap on TextView.
After all set onClickListener to your TextView.
I have the same problem with a ViewHolder in my RecyclerView.Adapter. So, I cut it for you if you need:
class RollHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnTouchListener {
private TextView textView;
RollHolder(View itemView) {
super(itemView);
textView = (TextView) itemView.findViewById(R.id.text_view);
textView.setOnClickListener(this);
textView.setOnTouchListener(this);
}
#Override
public void onClick(View view) {
switch (view.getId()){
case R.id.text_view:
// Do here that you need
break;
}
}
#Override
public boolean onTouch(View view, MotionEvent motionEvent) {
switch (view.getId()){
case R.id.text_view:
if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) view.requestFocus();
break;
};
return false;
}
}
I had the same problem and it's hard to ask and search for a resolution.
Here are two things that I noticed in addition to the double tap behavior:
if you really double tap (quickly) on a TextView with textIsSelectable, it selects the word you tapped, even when the focus is on something else, which means the view somehow registered the first touch as well.
if you long tap while the focus is somewhere else, it works and starts the selection action mode as if it was focused already
Here's how I managed to make it work. It's not beautiful, but everything works fine so far: in the XML you only need to add textIsSelectable, no other focusable / focusableInTouchMode / clickable / enabled attributes needed; then you need two listeners, one is the existing onClick which works, but needs a double take and the other is an onFocusChange where you handle the exceptional first tap:
hint = (TextView)view.findViewById(R.id.hint);
hint.setOnClickListener(new OnClickListener() {
#Override public void onClick(View v) {
handleHintClick();
}
});
hint.setOnFocusChangeListener(new OnFocusChangeListener() {
#Override public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus) { handleHintClick(); }
}
});
Here is an alternative solution in a related question which I don't like and didn't even try: wrap the TextView in a FrameLayout and add the listener to that.
Here is another related question which has more solutions.
Use onTouchListener to detect clicks and redirect them to the container view:
textView.setOnTouchListener { _, event ->
if (event.action == 1 && !textView.hasSelection()) {
containerView.callOnClick()
}
false
}
This will keep the ability to select and unselect text without calling onClick event.
android:longClickable="false"
android:clickable="false"
Disable the button with setEnabled(false) until it is safe for the user to click it again.
May this helpful to you
Try this.
use in XML file
android:onclick"your Name"//for example I used "onImageListClick"
public void onImageListClick(View view)
{
//do your task.
//Intent intent = new Intent(this, ImageListActivity.class);
//intent.putExtra(Extra.IMAGES, IMAGES);
//startActivity(intent);
}
or
txtboxname.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
////do you task.
}
});
I have an imageview - It has both the attributes -focusable and focusableintouchmode set to true
<ImageView
android:id="#+id/ivMenu01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:focusable="true"
android:focusableInTouchMode="true" >
</ImageView>
I have implemented the onFocusChangeListener in my activity-
#Override
public void onFocusChange(View v, boolean hasFocus) {
switch (v.getId()) {
case R.id.ivMenu01:
if (hasFocus) {
ivMenu01.setImageBitmap(Utility
.getBitmap("Home_ford_focus.png")); // Focussed image
} else {
ivMenu01.setImageBitmap(Utility.getBitmap("Home_ford.png")); // Normal image
}
break;
default:
break;
}
}
Also the onClickListener -
case R.id.ivMenu01:
ivMenu01.requestFocus();
Intent iFord = new Intent(HomeScreen.this, FordHome.class);
startActivity(iFord);
break;
Now when i click the ImageView the first click gives the focus to the ImageView and the second click performs the action.
I am not sure why this is happening .
The first click should request focus as well as perform the action.
Any help on how to do this will be highly appreciated.
It's the way the widget framework is designed.
When you look at View.onTouchEvent() code, you'll find out that the click action is performed only if the view has taken focus:
// take focus if we don't have it already and we should in
// touch mode.
boolean focusTaken = false;
if (isFocusable() && isFocusableInTouchMode() && !isFocused()) {
focusTaken = requestFocus();
}
if (!mHasPerformedLongPress) {
// This is a tap, so remove the longpress check
removeLongPressCallback();
// Only perform take click actions if we were in the pressed state
if (!focusTaken) {
// click
}
}
So, as you noticed, the first click makes the view gain focus. The second one will trigger the click handler since the view already has focus.
If you want to alter the bitmap of the ImageView when it's pressed, you should implement an View.OnTouchListener and set it via ImageView.setOnTouchListener() method. That listener should look more or less like this:
private View.OnTouchListener imageTouchListener = new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
// pointer goes down
ivMenu01.setImageBitmap(Utility.getBitmap("Home_ford_focus.png"));
} else if (event.getAction() == MotionEvent.ACTION_UP) {
// pointer goes up
ivMenu01.setImageBitmap(Utility.getBitmap("Home_ford.png"));
}
// also let the framework process the event
return false;
}
};
You can also use a Selector aka State List Drawable to achieve the same thing. See reference here: http://developer.android.com/guide/topics/resources/drawable-resource.html#StateList
Problem description:
I have a TextView on a RelativeLayout and I want to color it red when the user touches it, and go on another page when he clicks on it.
So I tried to set an OnClickListener to do the click, and an OnTouchListener to implement the touch function (MotionEvent.ACTION_DOWN) but this combination doesn't work, because OnTouchListener makes OnClickListener non-functional (don't know why).
On forums people say that we can implement the OnClick by the OnTouch MotionEvent.ACTION_UP, but this one can be triggered out of my TextView layout (the TextView gonna be clicked if you press it and drag your finger out of him to release) and this is not the desired behavior because I want:
click = press + release on the TextView.
Can someone give me a solution for this please?
you may call View.performClick() when action_up. Hope it helps.
your_txtView.setOnClickListener(new TextView.OnClickListener(){
public void onClick(View v) {
// TODO Auto-generated method stub
}
});
your_txtView.setOnTouchListener(new TextView.OnTouchListener(){
#Override
public boolean onTouch(View v, MotionEvent event) {
if (MotionEvent.ACTION_DOWN == event.getAction()) {
} else if (MotionEvent.ACTION_UP == event.getAction()) {
v.performClick();
}
return true;
}
});
Adel, is the problem with the first click, or you don't get any click at all?
There is this issue if you have multiple clickable layout you don't get any click events for the first. That's because it makes it first selected and then you get the click event, try the below code.
private class CustomTouchListener implements OnTouchListener {
#Override
public boolean onTouch(View v, MotionEvent event) {
TextView tv = (TextView) v.findViewById(R.id.single_line_text);
if (event.getAction() == MotionEvent.ACTION_DOWN) {
tv.setTextColor(COLOR_WHEN_PRESSED);
} else if (event.getAction() == MotionEvent.ACTION_UP) {
tv.setTextColor(COLOR_WHEN_RELEASED);
// Action of click goes here
} else if (event.getAction() == MotionEvent.ACTION_CANCEL) {
tv.setTextColor(COLOR_WHEN_RELEASED);
// To handle release outside the layout region
}
return false;
}
}
This is working in my current implementation if you set the touch listener for your layout.
You also need to set below on your layout
android:focusable="true"
android:focusableInTouchMode="true"
android:clickable="true"
Hope it helps!!!
EDIT: Additionally, there should be a flag in both DOWN and UP. Set it in DOWN and check if its set in UP. This will avoid a bug where user might tap anywhere in the screen and then hover on your textview and release it.
Had the same problem. Solved it by returning false from ACTION_MOVE. I've been fighting with it for few hours, trying various things, but seems like i've kept overlooking this little issue... And now it makes sense. When you return true from onTouch, futher processing is stopped, so that OnClickListener is not aware of any movements and triggers onClick even after pointer have moved outside of view.