i am creating a piano App in android studio. I am using the onTouch() method to check if the user has pressed a button and then play a sound. I have created two drawable resources for the piano keys, one is to be used when the piano keys are not pressed and another one to be used when a piano key is pressed. How do i set a condition inside my onTouch() method, to set the background to the respective drawable resources when the piano keys are pressed , and when they are not pressed? Thank you!
Here is the code
MainActivity.java
public class MainActivity extends AppCompatActivity implements View.OnTouchListener {
...
#Override
public boolean onTouch(View v, MotionEvent event) {
switch (v.getId()) {
case R.id.p1:
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:{
//set the background to key_pressed
soundPoolObject.play(c3, 1, 1, 0, 0, 1);
break;}
case MotionEvent.ACTION_UP:{
//set the background to key_normal
soundPoolObject.pause(c3);
break;}
}
}
return true;
}
}
Drawable resource key_pressed.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list
xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<solid android:color="#00000000" />
</shape>
</item>
<item android:top="10dp">
<shape android:shape="rectangle">
<corners android:radius="5dp" />
<solid android:color="#FFFFFF"/>
</shape>
</item>
</layer-list>
Drawable resource key_normal.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list
xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/black_shadow"/>
<item android:bottom="10dp" >
<shape android:shape="rectangle" >
<corners android:radius="5dp" />
<solid android:color="#FFFFFF"/>
</shape>
</item>
</layer-list>
Try this:
...
case R.id.p1:
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:{
//set the background to key_pressed
v.setBackgroundResource(R.drawable.key_pressed);
soundPoolObject.play(c3, 1, 1, 0, 0, 1);
break;}
case MotionEvent.ACTION_UP:{
//set the background to key_normal
v.setBackgroundResource(R.drawable.key_normal);
soundPoolObject.pause(c3);
break;}
}
...
Related
In my app I have created one Listview. When I click on the row, I want to change the Listview row color as Lightgray color and textcolor as a Blue color.
For this I have tried the code below but only row background color is changing not the textcolor.
mainListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
for (int j = 0; j < parent.getChildCount(); j++) {
parent.getChildAt(j).setBackgroundColor(Color.TRANSPARENT);
view.setBackgroundColor(Color.LTGRAY);
rowText = (TextView) findViewById(R.id.rowitem);
rowText.setTextColor(Color.BLUE);
}
}
});
}
first enable the android:ListSelector attribute in your ListView
ListView android:id="#+id/android:list" android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/Tablayoutdesign"
android:cacheColorHint="#000000"
android:dividerHeight="1dip"
android:layout_marginTop="63dip"
android:layout_marginBottom="40dip"
/>
Thank create a selector (listselector.xml)
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Selected -->
<item
android:state_focused="true"
android:state_selected="false"
android:drawable="#drawable/focused"/>
<!-- Pressed -->
<item
android:state_selected="true"
android:state_focused="false"
android:drawable="#drawable/selected" />
</selector>
Than go for colors.xml
<resources>
<drawable name="focused">#ff5500</drawable>
<drawable name="selected">#FF00FF</drawable>
</resources>
and with some Java magic:
listview.setSelector(R.drawable.listselector)
Thanks to #sankar-anesh
List State Pressed
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<solid android:color="#4285f4" />
<corners android:radius="2dp" />
</shape>
</item>
<item
android:bottom="2dp"
android:left="0dp"
android:right="0dp"
android:top="0dp">
<shape android:shape="rectangle">
<solid android:color="#4285f4" />
<corners android:radius="2dp" />
</shape>
</item>
</layer-list>
List view background when not pressed
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<solid android:color="#FFF" />
<corners android:radius="2dp" />
</shape>
</item>
<item
android:bottom="2dp"
android:left="0dp"
android:right="0dp"
android:top="0dp">
<shape android:shape="rectangle">
<solid android:color="#FFF" />
<corners android:radius="2dp" />
</shape>
</item>
</layer-list>
List view Selector
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/card_state_pressed" android:state_pressed="true" />
<item android:drawable="#drawable/card_background" />
</selector>
First create a selector drawable like this :
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#android:color/red"
android:state_pressed="true" />
<item android:drawable="#android:color/white" />
</selector>
Then
StateListDrawable selector = new StateListDrawable();
selector.addState(new int[] { android.R.attr.state_pressed }, getResources().getDrawable(R.color.red));
selector.addState(new int[] {}, getResources().getDrawable(R.color.white));
view.setBackgroundDrawable(selector);
Change the
rowText = (TextView) findViewById(R.id.rowitem);
to
rowText = (TextView)view.findViewById(R.id.rowitem);
since you should find the textview in the inflated view, not independently.
in my app there are three buttons yes no maybe. here I changed the colour of the button when user click any button that colour changed. when user clicks the button it stored as 1 0 2 in table based on user select the button. but when I go some other option in app and return back to this the buttons are as it normal. here that should be highlighted which is selected by user.
the following code for yes no maybe button
yesBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// highlight the button when clicked
yesBtn.setBackgroundColor(Color.YELLOW);
noBtn.setBackgroundColor(Color.BLUE);
maybeBtn.setBackgroundColor(Color.BLUE);
responseLayout.setVisibility(View.GONE);
//If user clicks yes button in invitation response layout,response would be stored as 1 for event user
final int response = 1;
final long eventId = eventMOs.get(position).getEventId();
userMO.setIsAttending(response);
new AsyncTask<Void, Void, String>() {
protected String doInBackground(Void... arg0) {
return userDelegate.updateEventUserRelationShipMapping(userMO, eventId);
}
}.execute(null, null, null);
}
});
noBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
yesBtn.setBackgroundColor(Color.BLUE);
noBtn.setBackgroundColor(Color.YELLOW);
maybeBtn.setBackgroundColor(Color.BLUE);
responseLayout.setVisibility(View.GONE);
//If user clicks no button in invitation response layout,response would be stored as 0 for event user
final int response = 0;
final long eventId = eventMOs.get(position).getEventId();
userMO.setIsAttending(response);
new AsyncTask<Void, Void, String>() {
protected String doInBackground(Void... arg0) {
return userDelegate.updateEventUserRelationShipMapping(userMO, eventId);
}
}.execute(null, null, null);
}
});
maybeBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
yesBtn.setBackgroundColor(Color.BLUE);
noBtn.setBackgroundColor(Color.BLUE);
maybeBtn.setBackgroundColor(Color.YELLOW);
responseLayout.setVisibility(View.GONE);
//If user clicks maybe button in invitation response layout,response would be stored as for event user
final int response = 2;
userMO.setIsAttending(response);
final long eventId = eventMOs.get(position).getEventId();
new AsyncTask<Void, Void, String>() {
protected String doInBackground(Void... arg0) {
return userDelegate.updateEventUserRelationShipMapping(userMO, eventId);
}
}.execute(null, null, null);
}
});
this yes no maybe layout shows when event is clicked
here events are list view when I clicked single event it should show for each event what I have clicked
use selectors for states like this hope this will help you...
create btn_stae.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" android:exitFadeDuration="#android:integer/config_shortAnimTime">
<item android:drawable="#drawable/hidden_bg" android:state_focused="true" android:state_pressed="false"/>
<item android:drawable="#drawable/bg_round" android:state_pressed="true"/>
<item android:drawable="#drawable/border" android:state_enabled="false"/>
<item android:drawable="#drawable/active" />
</selector>
active.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="4dp" />
<stroke
android:width="2dp"
android:color="#color/green_dark" />
<padding
android:bottom="10dp"
android:left="10dp"
android:right="10dp"
android:top="10dp" />
<solid android:color="#color/white" />
</shape>
border.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="4dp" />
<stroke
android:width="2dp"
android:color="#color/button_bg_stroke"/>
<padding
android:bottom="10dp"
android:left="10dp"
android:right="10dp"
android:top="10dp" />
<solid android:color="#color/button_bg" />
</shape>
bg_round.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#color/switch_thumb_normal_material_dark" />
<stroke
android:width="2dp"
android:color="#color/background_material_light" />
<padding
android:bottom="10dp"
android:left="10dp"
android:right="10dp"
android:top="10dp" />
<corners android:radius="4dp" />
</shape>
hidden_bg.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#color/bg" />
<stroke
android:width="2dp"
android:color="#color/light" />
<padding
android:bottom="10dp"
android:left="10dp"
android:right="10dp"
android:top="10dp" />
<corners android:radius="4dp" />
</shape>
If the requirement is only for save the 3 buttons state you can use sharedpreference to save the selected button value.
If yes is selected save value as 0, No is selected save as 1, May be clicked save 2.
Code to save value in sharedpreference. Write the similar code on your button click listeners.
SharedPreferences sharedpreferences = getSharedPreferences("PREFERENCE", Context.MODE_PRIVATE);
int clickedButton = sharedpreferences.getInt("clicked_btn", 1); //1 is the default value.
SharedPreferences sharedpreferences = getSharedPreferences("PREFERENCE", Context.MODE_PRIVATE);
Editor editor = sharedpreferences.edit();
editor.putInt("clicked_btn", 0); //value will be 0 or 1 or 2
editor.commit();
And get the saved value on next time in activity onResume() method like this
SharedPreferences sharedpreferences = getSharedPreferences("PREFERENCE", Context.MODE_PRIVATE);
int clickedButton = sharedpreferences.getInt("clicked_btn", 1); //1 is the default value.
Add switch case and change button color of last saved button based on the clickedButton value.
Switch case should be like this
switch (clickedButton)
{
case 0: //here change yes button color
break;
case 1: //here change no button color
break;
case 2: //here change may be button color
break;
default: //here default button color for saved button id
break;
}
Hope this will help for you.
I'm trying to draw drawable consisting of circle and rectangle. It's working fine while api is set to 23. I noticed that following attributes of 'item' have been added in newest api: height, gravity, weight. Is it possible to get the effect in older sdk?
Drawable:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:height="5dp"
android:gravity="center_vertical"
android:left="5dp">
<shape android:shape="rectangle">
<size
android:width="50dp"
android:height="5dp" />
<solid android:color="#125572" />
</shape>
</item>
<item
android:width="20dp"
android:height="20dp"
android:gravity="center_vertical">
<shape android:shape="oval">
<solid android:color="#125572" />
<size
android:width="20dp"
android:height="20dp" />
</shape>
</item>
</layer-list>
Image using api 23:
Image using api 22:
I know this question is quite old but I solved this problem and maybe it is useful for someone even now.
For the solution I created two classes.
One class called MyLayerDrawable that extends LayerDrawable. The important thing to keep in mind about this class is that you can get the top and the left insets for each layer.
public class MyLayerDrawable extends LayerDrawable{
private List<Layer> layers;
//some code here
public static class Layer{
private Drawable drawable;
private int topInset;
private int leftInset;
public Layer(Drawable drawable,int topInset,int leftInset){
this.leftInset=leftInset;
this.drawable=drawable;
this.topInset=topInset;
}
public Drawable getDrawable(){
return drawable;
}
public int getTopInset(){
return topInset;
}
public int getLeftInset(){return leftInset;}
}
The second class I created is called MyImageViewPatch that owns an ImageView.
The only public method of this class is setImageMyLayerDrawable(MyLayerDrawable layerDrawable). This method delegates setting the image drawable to the ImageView that it owns:
public void setImageMyLayerDrawable(MyLayerDrawable layerDrawable){
imageView.setImageDrawable(layerDrawable);
}
But before calling the setImageDrawable method an observer object has been added to the ImageView in the MyImageViewPatch constructor. This observer is called before drawing the Drawable in the ImageView:
imageView.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
#Override
public boolean onPreDraw() {
MyLayerDrawable layerDrawable=(MyLayerDrawable)imageView.getDrawable();
int numberOfLayers=layerDrawable.getNumberOfLayers();
Drawable drawable;
Rect bounds;
for(int i=0;i<numberOfLayers;i++){//for each layer
drawable=layerDrawable.getDrawable(i);
bounds=drawable.getBounds();
bounds.top=layerDrawable.getLayer(i).getTopInset();
bounds.left=layerDrawable.getLayer(i).getLeftInset();
if(drawable.getIntrinsicHeight()<bounds.height()){
bounds.bottom=drawable.getIntrinsicHeight()+layerDrawable.getLayer(i).getTopInset();
}
if(drawable.getIntrinsicWidth()<bounds.width()){
bounds.right=drawable.getIntrinsicWidth()+layerDrawable.getLayer(i).getLeftInset();
}
}
return true;
}
});
As you can see before drawing the MyLayerDrawable the bounds for each Layer are adjusted based on the left and top insets; this is the key part to get the drawables drawn in the correct size instead of stretched.
Here is the shapes xml file:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:height="5dp"
android:gravity="center_vertical"
android:left="5dp"
android:top="8dp">
<shape android:shape="rectangle">
<size
android:width="50dp"
android:height="5dp" />
<solid android:color="#125572" />
</shape>
</item>
<item
android:width="20dp"
android:height="20dp">
<shape android:shape="oval">
<solid android:color="#125572" />
<size
android:width="20dp"
android:height="20dp" />
</shape>
</item>
</layer-list>
To centre the rectangle vertically I used android:top="8dp" instead of android:gravity="center_vertical".
Here is the code for the Main Activity:
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ImageView iv=(ImageView)findViewById(R.id.imageView);
MyLayerDrawable myLayerDrawable=MyLayerDrawable.Builder.build(getApplicationContext(),R.drawable.layer_d_example);
MyImageViewPatch myImageViewPatch=new MyImageViewPatch(iv);
myImageViewPatch.setImageMyLayerDrawable(myLayerDrawable);
}
}
I have the complete code in github. You may check it out: https://github.com/marcosbses/my_layout_drawable.git
I have made a custom_button.xml in my drawable folder for when my buttons are pressed, and for default. It looks as follows:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" >
<shape>
<gradient
android:startColor="#color/red"
android:endColor="#color/light_red"
android:angle="270" />
<corners
android:radius="5dp" />
</shape>
</item>
<item>
<shape>
<gradient
android:startColor="#color/light_purple"
android:endColor="#color/purple"
android:angle="270" />
<corners
android:radius="5dp" />
</shape>
</item>
My buttons look fine when not pressed, it shows the default purple button. But when I press it, it does not change to the red button as it should be when state_pressed.
In my activity_main.xml, the buttons are defined as follows:
<Button
android:id="#+id/button1"
android:layout_width="0dp"
android:layout_height="fill_parent"
android:layout_weight="1"
android:background="#drawable/custom_button"
android:layout_margin="5dp"/>
I'm using nested LinearLayout if that makes any difference.
Please let me know if there's something I've missed!
EDIT: I found out the source of the problem, but not sure how to fix it. When I remove these following listeners from my createListeners, the buttons change color as they should.
b1.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_DOWN) {
int beat = getBeat(1);
m1 = MediaPlayer.create(MainActivity.this, beat);
m1.start();
m1.setLooping(true);
return true;
} else if (event.getAction() == MotionEvent.ACTION_UP) {
m1.release();
}
return false;
}
});
What it's basically doing is that it plays a song for as long as the button is pressed. How does this interfere with the button color?
It seems that onTouchListener() doesn't work correctly with selector. You have to change background manually in ACTION_DOWN and ACTION_UP.
I tried your selector and it is working on my side.
I noticed that the width of your button is 0dp and when
I used that XML on my side, it doesn't work.
Try changing it to this:
<Button
android:id="#+id/button1"
android:layout_width="warap_content"
android:layout_height="fill_parent"
android:layout_weight="1"
android:text="test"
android:background="#drawable/custom_button"
android:layout_margin="5dp"/>
And this is the custom_buttom.xml that I used:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:state_pressed="true" >
<shape>
<gradient
android:startColor="#FF0000"
android:endColor="#FF00FF"
android:angle="270" />
</shape>
</item>
<item>
<shape>
<gradient
android:startColor="#1E669B"
android:endColor="#1E669B"
android:angle="270" />
</shape>
</item>
</selector>
Alright, so I've managed to make it work but it might be a roundabout way of doing it. I basically changed the setOnTouchListener so it looks like this:
b1.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_DOWN) {
int beat = getBeat(1);
m1 = MediaPlayer.create(MainActivity.this, beat);
m1.start();
m1.setLooping(true);
b1.setPressed(true);
return true;
} else if (event.getAction() == MotionEvent.ACTION_UP) {
b1.setPressed(false);
m1.release();
}
return false;
}
});
Just manually changing the pressed state of the button.
I want to change color of underline in Edittext and i follow some tutorials to do this.
I create this xml file:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item>
<shape android:shape="rectangle" >
<solid android:color="#00FFFFFF" />
<padding android:bottom="2dp" />
<stroke
android:width="1dp"
android:color="#FFFFFF" />
</shape>
</item>
</layer-list>
But i only do the underline not all rectangle, similiar as default line but white inside of blue and solid background transpartet.
How can i do this?
Thanks
You can change it programatically too:
public static void changeEditTextUnderlineColor(EditText editText) {
int color = Color.parse("#[putColorHere]")
Drawable drawable = editText.getBackground();
drawable.setColorFilter(color, PorterDuff.Mode.SRC_ATOP);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
editText.setBackground(drawable);
} else {
editText.setCompoundDrawables(null, null, drawable, null);
}
}
you can change Edit color Underline in EditText specifying it in styles.xml. In your app theme styles.xml add the following.
<item name="android:textColorSecondary">#color/primary_text_color</item>