Scrollbar touch area in Android 6 - android

I observe new behaviour in Android 6.0 Marshmallow. The touching area of scrollbar is widther than the scrollbar. It is visible on following screenshot. Scrollbar has 20 dp (green area) and touching area is probably 48 dp (blue and green area). I would like to have the touch area above the scrollbar only:
I use following:
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<style name="MyTheme.Dark" parent="android:Theme.Black">
<item name="android:fastScrollStyle">#style/Widget.FastScroll</item>
<item name="android:scrollbarThumbVertical">#drawable/dark_scrollbar_thumb</item>
<item name="android:scrollbarTrackVertical">#drawable/dark_scrollbar_track</item>
<item name="android:scrollbarSize">4dp</item>
<item name="android:fastScrollThumbDrawable">#drawable/dark_scrollbar_fast_thumb</item>
<item name="android:fastScrollTrackDrawable">#drawable/dark_scrollbar_fast_track</item>
</style>
<style name="Widget.FastScroll" parent="android:Widget.Material.FastScroll">
</style>
</resources>
dark_scrollbar_fast_thumb.xml:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item>
<shape>
<size
android:height="30dp"
android:width="20dp" />
<solid android:color="#android:color/transparent" />
</shape>
</item>
<item android:left="8dp" android:right="8dp">
<shape>
<size
android:height="30dp"
android:width="4dp" />
<solid android:color="#color/dark_secondary" />
</shape>
</item>
</layer-list>
dark_scrollbar_fast_track.xml:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
<size android:width="#dimen/1dp" />
<solid android:color="#color/dark_scrollbar_track" />
</shape>
dark_scrollbar_fast_thumb.xml:
<item>
<shape>
<size
android:height="30dp"
android:width="20dp" />
<solid android:color="#android:color/transparent" />
</shape>
</item>
<item android:left="8dp" android:right="8dp">
<shape>
<size
android:height="30dp"
android:width="4dp" />
<solid android:color="#color/dark_secondary" />
</shape>
</item>
dark_scrollbar_fast_track.xml:
<size android:width="#dimen/1dp" />
<solid android:color="#color/dark_scrollbar_track" />
Fast scrollbar is always visible and I use following style in listviews:
<item name="android:scrollbarStyle">outsideInset</item>
But the result looks more like outsideOverlay. I can observe this issue only on Marshmallow devices.
I would like to find the attribute that causes it and change it from 48dp to 20dp. Would you please help me?

I encountered the same issue and ended up using a workaround.
The trick is to disable the fast scroll when the user is not scrolling (or 1 sec after he stopped scrolling), and reactivate it when he starts scrolling again.
In order to do so, youn need to implement OnScrollListener like this and set the listener to the listview:
private int mCurrentState = 0;
#Override
public void onScrollStateChanged(AbsListView absListView, int state) {
if (state == SCROLL_STATE_IDLE && mCurrentState != state && mListview.isFastScrollEnabled()){
mListview.postDelayed(new Runnable() {
#Override
public void run() {
mListview.setFastScrollEnabled(false);
}
},1000);
}
mCurrentState = state;
}
#Override
public void onScroll(AbsListView absListView, int i, int i1, int i2) {
if (mCurrentState == SCROLL_STATE_TOUCH_SCROLL) {
if (!mListview.isFastScrollEnabled())
mListview.setFastScrollEnabled(true);
}
}
Hope this might help you

Found a simple solution which honestly I don't understand completely ;)
I created a view overlay for the blue section which should be touch insensitive for the fastscrollbar (parent view is a RelativeLayout).
<View
android:id="#+id/scroll_overlay
android:layout_width="25dp"
android:layout_marginRight="25dp"
android:alignParentTop="true"
android:alignParentRight="true"
android:layout_above="#id/my_list_view_bottom_bar"
android:clickable="true"/>
Then in my list view fragment, I set up an OnTouchListener for the overlay view to catch the touch events. The idea was to catch the MotionEvent.ACTION_DOWN to avoid jumping to the fast scrollbar position. But following code does that already.
View scrollOverlay = (View)view.findViewById(R.id.scroll_overlay);
scrollOverlay.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
return myListView.onTouchEvent(event);
}
});

Related

Round button without corners in Android [duplicate]

MOCK UP
Requirement
I want to put custom button with selector.
Mock up is given above.
If anyone knows solution then share it.
Thank you.
basically you will need to create some new XML files and apply them to your Button element. As i can see from the mockup you will need a stroke and the background color with some shading effect applied, you can research more into the shading thing but the background color and the stroke is pretty straight forward.
Here is an example, done_rounded_btn.xml:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_pressed="true"
android:state_enabled="true"
android:drawable="#drawable/zzzzzzzzz_btn_orange" />
<item
android:state_focused="true"
android:state_enabled="true"
android:drawable="#drawable/zzzzzzzzz_btn_orange" />
<item
android:state_focused="false"
android:state_enabled="false"
android:drawable="#drawable/zzzzzzzzz_btn_inactiv" />
<item android:drawable="#drawable/zzzzzzzzz_btn_black"/>
</selector>
for the selection part and then you create the custom drawables corresponding to the mockup.
An example, zzzzzzzzzz_btn_orange:
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<solid
android:color="#color/done_color">
</solid>
<corners
android:bottomLeftRadius="3dp"
android:bottomRightRadius="3dp"
android:topLeftRadius="3dp"
android:topRightRadius="3dp" />
</shape>
And then add it to your button as background, main.xml:
<Button
android:id="#+id/registers_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginBottom="10dp"
android:layout_marginLeft="15dp"
android:layout_marginTop="10dp"
android:background="#drawable/done_rounded_btn"
android:text="#string/done_txt"
android:textColor="#color/white"
android:textSize="15sp" />
Hope this helps!
You can use this instead of standard Button and set selector as background in xml:
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.Button;
/**
* Custom Shape Button which ignores touches on transparent background.
*/
public class ButtonWithUntouchableTransparentBg extends Button {
public ButtonWithUntouchableTransparentBg(Context context) {
this(context, null);
}
public ButtonWithUntouchableTransparentBg(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public ButtonWithUntouchableTransparentBg(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
setDrawingCacheEnabled(true);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
int x = (int) event.getX();
int y = (int) event.getY();
// ignores touches on transparent background
if (isPixelTransparent(x, y))
return true;
else
return super.onTouchEvent(event);
}
/**
* #return true if pixel from (x,y) is transparent
*/
private boolean isPixelTransparent(int x, int y) {
Bitmap bmp = Bitmap.createBitmap(getDrawingCache());
int color = Color.TRANSPARENT;
try {
color = bmp.getPixel(x, y);
} catch (IllegalArgumentException e) {
// x or y exceed the bitmap's bounds.
// Reverts the View's internal state from a previously set "pressed" state.
setPressed(false);
}
// Ignores touches on transparent background.
if (color == Color.TRANSPARENT)
return true;
else
return false;
}
}
You can also create a shape that is using a selector inside. If your shape is just changing its color in different states, this is a lot cleaner.
color/color_selector.xml
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="#color/blue_dark" android:state_pressed="true" />
<item android:color="#color/blue_light" />
</selector>
drawable/shape.xml
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#color/color_selector" />
<corners android:bottomLeftRadius="6dip" android:bottomRightRadius="6dp" />
<padding android:bottom="0dip" android:left="0dip" android:right="0dip" android:top="0dip" />
</shape>
Button with rounded corners with two states (enabled/disabled):
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_enabled="true">
<shape android:shape="rectangle">
<corners android:radius="28dp" />
<solid android:color="#color/white" />
<stroke android:width="1dp" android:color="#color/orange" />
</shape>
</item>
<item android:state_enabled="false">
<shape android:shape="rectangle">
<corners android:radius="28dp" />
<solid android:color="#color/grey_card_background" />
<stroke android:width="1dp" android:color="#color/grey" />
</shape>
</item>
</selector>
inside your item put the shape in the selector XML
EX FROM MY CODE :
<!-- if pressed -->
<item android:state_pressed="true"><shape android:padding="10dp" android:shape="rectangle">
<solid android:color="#color/blue" />
<corners android:bottomLeftRadius="10dp" android:bottomRightRadius="10dp" android:topLeftRadius="10dp" android:topRightRadius="10dp" />
</shape></item>
<!-- if not pressed -->
<item><shape android:padding="10dp" android:shape="rectangle">
<solid android:color="#color/Purbble" />
<corners android:bottomLeftRadius="10dp" android:bottomRightRadius="10dp" android:topLeftRadius="10dp" android:topRightRadius="10dp" />
</shape></item>

SeekBar secondaryProgress not showing

I have a question, I have a seek bar and I want to show the buffer progress of an ExoPlayer media file using the secondary progress bar of the seekBar, the problem is that it´s not showing. Im running on API 21
Here´s the xml code:
<SeekBar
android:id="#+id/seekBarAudioA"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:maxHeight="3dip"
android:minHeight="3dip"
android:progressDrawable="#drawable/seek_bar_progress"
android:secondaryProgressTint="#android:color/holo_blue_dark"
android:thumbTint="#color/amber"
app:layout_constraintBottom_toBottomOf="#+id/play_pause"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintLeft_toRightOf="#+id/play_pause"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="#+id/play_pause" />
and here´s the java code:
SeekBar = new Thread(new Runnable() {
#Override
public void run() {
try {
while (currentlyPlaying && currentAudioHolder.getAdapterPosition() == audioPosition) {
int duration = (int) exoPlayer.getDuration();
currentAudioHolder.seekBarAudio.setMax(duration);
currentAudioHolder.seekBarAudio.setSecondaryProgress((int) exoPlayer.getBufferedPosition());
final int currPosition = (int) exoPlayer.getCurrentPosition();
Log.d("Buffer", "secondary progress bar position is: " + (int) exoPlayer.getBufferedPosition() + ", and the current position is: " + currPosition);
currentAudioHolder.seekBarAudio.setProgress(currPosition);
((ChatActivity) context).runOnUiThread(new Runnable() {
#Override
public void run() {
currentAudioHolder.audioLength.setText(convertTime(currPosition));
}
});
Thread.sleep(sleep);
}
} catch (InterruptedException i) {
currentlyPlaying = false;
}
}
});
SeekBar.start();
Please help :(
I might be late, but here is my answer: you should check your seek_bar_progress file, that you use for android:progressDrawable, and see if it looks like this:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="#android:id/background">
<shape android:shape="rectangle">
<corners android:radius="2dp"/>
<solid android:color="#color/myBgColor"/>
</shape>
</item>
<item android:id="#android:id/secondaryProgress">
<scale android:scaleWidth="100%">
<shape android:shape="rectangle">
<corners android:radius="2dp"/>
<solid android:color="#color/myColor"/>
</shape>
</scale>
</item> <item android:id="#android:id/progress">
<clip>
<shape android:shape="rectangle">
<corners android:radius="2dp"/>
<solid android:color="#color/myColor"/>
</shape>
</clip>
</item>
</layer-list>
I found out that the part with the #android:id/secondaryProgress id was missing in my drawable, and that was the reason why it was not working for me.
Hope it helps.

Android: Add divider between items in RecyclerView

I am using RecyclerView with rounded corner, to make it rounded corner I used below XML:
view_rounded.xml:-
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#008f8471"/>
<stroke android:width="2dp" android:color="#ffffff" />
<corners android:radius="10dp"/>
</shape>
fragment_main.xml:-
<android.support.v7.widget.RecyclerView
android:id="#+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/view_rounded"/>
adapter_main.xml:-
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/LinearLayout1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="#+id/textTitle"
style="#style/AppTheme.ListTextView"
/>
</LinearLayout>
style.xml:-
<style name="AppTheme.ListTextView" parent="android:Widget.Material.TextView">
<item name="android:gravity">left</item>
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:textAllCaps">false</item>
<item name="android:padding">10dp</item>
<item name="android:textAppearance">#android:style/TextAppearance.DeviceDefault.Medium</item>
<item name="android:textColor">#color/tabsScrollColor</item>
<item name="android:textStyle">bold</item>
</style>
Getting (without item separator):
Required (with item separator):
you should try add Divider
mListview.addItemDecoration(new DividerItemDecoration(this.getActivity(), LinearLayout.VERTICAL));
I have done this way:
onCreateView() of Fragment:
RecyclerView recyclerView = (RecyclerView) rootView.findViewById(R.id.recyclerView);
recyclerView.addItemDecoration(new SimpleDividerItemDecoration(getActivity()));
SimpleDividerItemDecoration.java:
public class SimpleDividerItemDecoration extends RecyclerView.ItemDecoration {
private Drawable mDivider;
public SimpleDividerItemDecoration(Context context) {
mDivider = context.getResources().getDrawable(R.drawable.recycler_horizontal_divider);
}
#Override
public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
int left = parent.getPaddingLeft();
int right = parent.getWidth() - parent.getPaddingRight();
int childCount = parent.getChildCount();
for (int i = 0; i < childCount; i++) {
View child = parent.getChildAt(i);
RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
int top = child.getBottom() + params.bottomMargin;
int bottom = top + mDivider.getIntrinsicHeight();
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(c);
}
}
}
recycler_horizontal_divider.xml:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<size
android:width="1dp"
android:height="1dp" />
<solid android:color="#2EC590" />
</shape>
Hope this will help you.
RecyclerView works different from ListViews. You need to add ItemDecorators for the recycler view. As the docs says,
An ItemDecoration allows the application to add a special drawing and layout offset to specific item views from the adapter's data set. This can be useful for drawing dividers between items, highlights, visual grouping boundaries and more.
Take a look into this link : https://developer.android.com/reference/android/support/v7/widget/RecyclerView.ItemDecoration.html
Well what I did to achieve this is, I first created layout for my adapter row as
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/LinearLayout1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<View
android:id="#+id/lineView"
android:layout_width="match_parent"
android:layout_height="2px"
android:background="#android:color/black"/>
<TextView
android:id="#+id/textTitle"
style="#style/AppTheme.ListTextView"
/>
</LinearLayout>
Then in my adapter I checked for first row and changed its viewLine Visibility to invisible
#Override
public void onBindViewHolder(ChildInfoViewHolder holder, final int position) {
if(position == 0){
holder.viewLine.setVisibility(View.INVISIBLE);
}
//...
}
public static class MyViewHolder extends RecyclerView.ViewHolder{
protected View viewLine;
public ChildInfoViewHolder(View view) {
super(view);
viewLine = view.findViewById(R.id.viewLine);
//...
}
}
To add dividers to your recyclerview you need to use decorator - https://gist.github.com/alexfu/0f464fc3742f134ccd1e after you add that to your project add a line
recyclerView.addItemDecoration(new DividerItemDecoration(getActivity(), DividerItemDecoration.VERTICAL_LIST));
This line of code worked for me:
recyclerView.addItemDecoration(new DividerItemDecoration(context, DividerItemDecoration.HORIZONTAL));
For vertical line, pass second argument as DividerItemDecoration.VERTICAL.
Set the selector at the background of the list item in your layout if you are using custom adapter
Try this one:
A very nice solution by Michel-F. Portzert
public class ClippedListView extends ListView {
public ClippedListView(Context context) {
super(context);
}
public ClippedListView(Context context, AttributeSet attrs) {
super(context, attrs);
}
#Override
protected void dispatchDraw(Canvas canvas) {
float radius = 10.0f;
Path clipPath = new Path();
RectF rect = new RectF(0, 0, this.getWidth(), this.getHeight());
clipPath.addRoundRect(rect, radius, radius, Path.Direction.CW);
canvas.clipPath(clipPath);
super.dispatchDraw(canvas);
}
}
Try This From
Reference
Android: ListView with rounded corners
First off, we need the drawables for the backgrounds of the Lists entries:
For the entries in the middle of the list, we don't need rounded corners, so create a xml in your drawable folder "list_entry_middle.xml" with following content:
<?xml version="1.0" encoding="UTF-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape>
<stroke android:width="1px" android:color="#ffbbbbbb" />
</shape>
</item>
<item android:bottom="1dp" android:left="1dp" android:right="1dp">
<shape >
<solid android:color="#ffffffff" />
</shape>
</item>
</layer-list>
For the rounded corners, create another xml, "rounded_corner_top.xml":
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape>
<stroke android:width="1dp" android:color="#ffbbbbbb" />
<corners android:topLeftRadius="20dp"
android:topRightRadius="20dp"
/>
</shape>
</item>
<item android:top="1dp" android:left="1dp" android:right="1dp" android:bottom="1dp">
<shape >
<solid android:color="#ffffffff" />
<corners android:topLeftRadius="20dp"
android:topRightRadius="20dp"
/>
</shape>
</item>
</layer-list>
Implementing the bottom part is quite the same, just with bottomLeftRadius and bottomRightRadius. (maybe also create one with all corners rounded, if the list only has one entry)
For better usability, also provide drawables with other colors for the different states, that the list item can have and reference them in another xml in the drawable folder ("selector_rounded_corner_top.xml") as followed:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/rounded_corner_top_click"
android:state_pressed="true" />
<item android:drawable="#drawable/rounded_corner_top_click"
android:state_focused="true" />
<item android:drawable="#drawable/rounded_corner_top" />
</selector>
Now do the same for the other backgrounds of the list.
All that is left now, is to assign the right backgrounds in our ListAdapter like following:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
//...
//skipping the view reuse stuff
if (position == 0 && entry_list.size() == 1) {
view.setBackgroundResource(R.drawable.selector_rounded_corner);
} else if (position == 0) {
view.setBackgroundResource(R.drawable.selector_rounded_corner_top);
} else if (position == entry_list.size() - 1) {
view.setBackgroundResource(R.drawable.selector_rounded_corner_bottom);
} else {
view.setBackgroundResource(R.drawable.selector_middle);
}
//...
//skipping the filling of the view
}
Modify your ListView like below.Add the list_bg as the background of your ListView Also specify some padding for the top and the bottom of the listView otherwise the 1st and the last item in the list will overlap with the rounded corners showing rectangular corners.
<ListView
android:id="#+id/listView"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:background="#drawable/list_bg"
android:paddingTop="10dp"
android:paddingBottom="10dp"
android:fastScrollEnabled="true"
android:choiceMode="singleChoice" />
Use this drawable xml for curve shape listview and set background to your list view or any layout:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="6dp" />
<padding android:bottom="3dp" android:left="3dp" android:right="3dp" android:top="3dp" />
</shape>
Try this
custom_rounded_list.xml :
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<gradient
android:startColor="#ff2521"
android:endColor="#2f5511"
android:angle="270"/>
<padding
android:bottom="5dp"
android:left="5dp"
android:right="5dp"
android:top="5dp" />
<corners
android:bottomRightRadius="7dp"
android:bottomLeftRadius="7dp"
android:topLeftRadius="7dp"
android:topRightRadius="7dp" />
</shape>
Your listview:
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/mylst"
android:background="#drawable/custom_rounded_list" />
you are setting list_selector for both textview and listview background. Use list_selector only for listview and if you want hover effect on textview too, then create another list_selector_textview which haven't include the <corners android:radius="10dp" property.
The problem is because you are setting the background with corners not only to the list view, but also to the item. You should make separate backgrounds for item (with selector) and one for list view with corners.
list_bg.xml
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#008f8471"/>
<stroke android:width="1dip" android:color="#ffffff" />
<corners android:radius="10dp"/>
<padding android:left="0dip" android:top="0dip" android:right="0dip" android:bottom="0dip" />
</shape>
Now you can setup this drawable as the background of your list view.
<ListView
android:id="#+id/listView"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:background="#drawable/list_bg.xml"
android:fastScrollEnabled="true"
android:choiceMode="singleChoice" />
And for list view item you can use selector to have hover functionality:
list_item_selector.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/list_item_selected" android:state_pressed="true"/>
<item android:drawable="#drawable/list_item_selected" android:state_pressed="false" android:state_selected="true"/>
<item android:drawable="#android:color/transparent"/>
Where list_item_selected is :
list_item_selected.xml
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#4d8f8471"/>
<stroke android:width="1dip" android:color="#ffffff" />
</shape>
And after that you can setup this selector to the item in your xml:
<TextView
android:id="#+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/list_item_selector" />
So your list view will have always same background with corners, and the background of items of list view, will be without corners and will be changed in pressed or selected state.
Just One Line...
recyclerView.addItemDecoration(new DividerItemDecoration(getActivity(), null));
That's all
Try this
recyclerView.apply {
....
addItemDecoration(DividerItemDecoration(context, DividerItemDecoration.VERTICAL))
}

How do i change text color when button was pressed once (Android)

what i basically wanna do is this:
When i click on the button i want its Text color to appear in a different color.
What i tried is this:
<selector
xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_pressed="true"
android:color="#color/red" />
<item
android:state_pressed="false"
android:color="#000" />
</selector>
and then i did use this selector as drawable on the button android:textColor
but this doesn solve it since it only changes its color while i press the button.
I want it like this:
Default: black
on click: blue
on click again: black
any ideas how to do that? :S
this is my shape for the button (if it matters):
<?xml version="1.0" encoding="utf-8"?>
<inset xmlns:android="http://schemas.android.com/apk/res/android"
android:insetBottom="-1dp"
android:insetLeft="-1dp"
android:insetRight="-1dp">
<selector>
<item android:state_pressed="false">
<shape android:shape="rectangle" >
<corners
android:radius="0dp"
/>
<solid
android:color="#color/background_grey"
/>
<padding
android:left="0dp"
android:top="0dp"
android:right="0dp"
android:bottom="0dp"
/>
<size
android:width="100dp"
android:height="30dp"
/>
<stroke
android:width="1dp"
android:color="#ffb4b4b4"
/>
</shape>
</item>
<item android:state_pressed="true">
<shape android:shape="rectangle" >
<corners
android:radius="0dp"
/>
<solid
android:color="#color/pq_blue"
/>
<padding
android:left="0dp"
android:top="0dp"
android:right="0dp"
android:bottom="0dp"
/>
<size
android:width="100dp"
android:height="30dp"
/>
<stroke
android:width="1dp"
android:color="#ffb4b4b4"
/>
</shape>
</item>
</selector>
</inset>
thx in advance
EDIT
so i tried to do it programatically and tied the folowing just to see if it changes color´s ..but yea..it doesn´t (it seems like my onCLick event doesnt work):
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.listview_item, container, false);
final Button likeButton = (Button)rootView.findViewById(R.id.btLike);
likeButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String test = "tester";
if(BUTTON_STATE==BUTTON_STATE_ONCE){
likeButton.setTextColor(getResources().getColor(R.color.pq_blue));
BUTTON_STATE = BUTTON_STATE_TWICE;
}else{
likeButton.setTextColor(getResources().getColor(R.color.red));
BUTTON_STATE = BUTTON_STATE_ONCE;
}
}
});
return rootView;
}
}
NOTE: i do all tht stuff in onCreateView since im in a Fragment of my ActionBarActivity(with tabs) if im doing it in the onCreate i get a null pointer exception at findViewById ( since it searches for the ID in my mainActivity, if im right?)
so yea..any ideas?
Your textselector.xml -
<selector
xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_pressed="true"
android:color="#color/red" /> <!--selected text colour-->
<item
android:state_focused="true"
android:color="#color/red" />
<item
android:color="#color/blue" /> <!--unselected text colour-->
</selector>
Your button in layout.xml -
<Button
android:id="#+id/btn1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Exit"
android:textColor="#drawable/textselector" <!-- SET textselector HERE -->
android:background="#drawable/button_color"/>
You can use this code to do it programmatically:
myButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
ColorStateList myList=myButton.getTextColors();
int myColor=myList.getDefaultColor();
switch(myColor)
{
case Color.BLACK:
myButton.setTextColor(Color.BLUE);
break;
case Color.BLUE:
myButton.setTextColor(Color.BLACK);
break;
}
}
});
If You want to have a behaviour like:
First Click: Button text black
Second Click: Button text blue
third Click: button text black again
I don´t think it´s possible with the selector, also not with state focused. Because if any other view will be clicked, the button is not focused anymore and will loose the textcolor, goes back to default. You have to do it in a programmatically way:
First, set the default textColor to what You want: black inside Your xml. So than You have the color on no press. make a globa variabel to save the state:
private int BUTTON_STATE = 0;
private final int BUTTON_STATE_ONCE = 0;
private final int BUTTON_STATE_TWICE = 1;
button.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
if(BUTTON_STATE==BUTTON_STATE_ONCE){
button.setTextColor(Color.BLUE);
BUTTON_STATE = BUTTON_STATE_TWICE;
}else if(BUTTON_STATE==BUTTON_STATE_TWICE){
button.setTextColor(Color.BLACK);
BUTTON_STATE = BUTTON_STATE_ONCE;
}
}
});
That´s just a possible solution, there are many ways..
EDIT
for Your code:
Create that global variables like i did in my example above, and use them in the if/else statement:
likeButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(BUTTON_STATE==BUTTON_STATE_ONCE){
likeButton.setTextColor(getResources().getColor(R.color.pqBlue));
BUTTON_STATE = BUTTON_STATE_TWICE;
}else if(BUTTON_STATE==BUTTON_STATE_TWICE){
likeButton.setTextColor(getResources().getColor(R.color.pqBlack));
BUTTON_STATE = BUTTON_STATE_ONCE;
}
}
});
Try adding text_effect.xml drawable
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true"
android:color="#color/white" /> <!-- pressed -->
<item android:color="#color/black" /> <!-- default -->
</selector>
add this line in button control
android:textColor="#drawable/text_effect"
It will work. Enjoy:)
If you do not mandatorily need a simple Button, you could use a ToggleButton that is made for binary-state handling... With a ToggleButton your selector would look like this :
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="true" android:color="#color/red" />
<!-- Default State -->
<item android:color="#000" />
</selector>
It seems like you wanna implement something like toggle button.
Instead of button u can use toggle button.
Though if you wanna use button only then u need to do some changes in your java code as well as xml code also
Create a file def_btn.xml it will look like this..
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<corners
android:radius="0dp"
/>
<solid
android:color="#color/background_grey"
/>
<padding
android:left="0dp"
android:top="0dp"
android:right="0dp"
android:bottom="0dp"
/>
<size
android:width="100dp"
android:height="30dp"
/>
<stroke
android:width="1dp"
android:color="#ffb4b4b4"
/>
</shape>
Create another file press_btn.xml it will look like this..
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<corners
android:radius="0dp"
/>
<solid
android:color="#color/pq_blue"
/>
<padding
android:left="0dp"
android:top="0dp"
android:right="0dp"
android:bottom="0dp"
/>
<size
android:width="100dp"
android:height="30dp"
/>
<stroke
android:width="1dp"
android:color="#ffb4b4b4"
/>
</shape>
Inside your activity declare a private boolean variable(say isPressed) by default isPressed is false. & for default button background will be def_btn.xml
Now write following in button's onClick event.
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
isPressed = !isPressed;
if(isPressed){
btn.setBackgroundResource(R.drawable.def_btn);
}else{
btn.setBackgroundResource(R.drawable.press_btn);
}
}
});
That's it..

Android Onclick

How are you? I am new at Android programming. so far I have run a single app on my mobile phone using 4.1 API 16.
My question is when releasing a click event the button image in the following code should be restored to previous state.
button.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
x = x + 1;
edittext.setText("" + x);
button.setBackgroundResource(R.drawable.buttonpressed1);
}
});
you can also use drawable touch states. an example showing color change on press:
in your button xml use android:background="#drawable/touchstates"
and touchstates.xml:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true">
<shape android:shape="rectangle">
<stroke android:color="#cc0099CC" android:width="1dip" />
<solid android:color="#660099CC" />
</shape>
</item>
</selector>
For normal performance you must use selector like background property of Button view
put all of this files to folder drawable
selector.xml:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/bg_pressed" android:state_pressed="true" />
<item android:drawable="#drawable/br_unpressed" />
</selector>
bg_pressed.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<stroke
android:width="#dimen/circle_padding"
android:color="#android:color/transparent" />
<solid android:color="#android:color/white" />
</shape>
bg_unpressed.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<stroke
android:width="#dimen/circle_padding"
android:color="#android:color/transparent" />
<solid android:color="#android:color/black" />
</shape>
and in layout set button background android:background="#drawable/selector"
There is a full solution for you:
ImageButton guessButton;
guessButton = (ImageButton) findViewById(R.id.Knorr_Game_Guess_Button);
guessButton.setOnTouchListener(new View.OnTouchListener()
{
#Override
public boolean onTouch(View v, MotionEvent event)
{
if (event.getAction() == MotionEvent.ACTION_DOWN)
{
v.setBackgroundResource(R.drawable.ic_picture1);
}
else if (event.getAction() == MotionEvent.ACTION_UP)
{
v.setBackgroundResource(R.drawable.ic_picture2);
}
return false;
}
});
It works:)
If you want to capture the release of a button, you need to use OnTouchListener
Here is an example:
yourButton.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_DOWN) {
//What happens when preessed
} else if (event.getAction() == MotionEvent.ACTION_UP) {
//What happens when released }
}
};
Hope this helped!
You need to use a selector. The selector needs to be a drawable file which is assigned to the background of your button. An example of a selector
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- focused -->
<item
android:state_focused="true"
android:drawable="#drawable/rounded_button_focused"
/>
<!--pressed -->
<item
android:state_pressed="true"
android:drawable="#drawable/rounded_button_pressed"
/>
<item
android:drawable="#drawable/rounded_button_unfocused"/>
</selector>
The selector will basically assign the correct background depending on the state of your button. If the button is pressed then it will assign the file "rounded_button_pressed" to the background of the button. The rounded_button_pressed is another drawable file for example:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<gradient android:startColor="#color/WhiteSmoke"
android:endColor="#color/LightGrey"
android:angle="270"/>
<stroke
android:width="2dp"
android:color="#color/CornflowerBlue" />
<corners
android:radius="4dp"
/>
<padding
android:left="10dp"
android:top="10dp"
android:right="10dp"
android:bottom="10dp" />
</shape>
Hope it solves your problem

Categories

Resources