I am not able to use ripple effect on pressing on a tab please help I have tried a lot and struggling with it whole day.How can I use ripple effect on both pre-lollipop and lollipop devices any suggestion?
MainActivity.java
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mPager=(ViewPager)findViewById(R.id.pager);
mPager.setAdapter(new MyPagerAdapter(getSupportFragmentManager(),getApplicationContext()));
mTabs=(SlidingTabLayout)findViewById(R.id.tabs);
mTabs.setDistributeEvenly(true);
mTabs.setCustomTabView(R.layout.customtablayout,R.id.textTab);
mTabs.setBackgroundColor(getResources().getColor(R.color.colorAccent));
mTabs.setSelectedIndicatorColors(getResources().getColor(R.color.colorPrimary));
mTabs.setViewPager(mPager);
}
activitymain.xml
<sarveshchavan777.inrerface2.SlidingTabLayout
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
customtablayout.xml
<ImageView
android:id="#+id/imageTab"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center" />
<TextView
android:id="#+id/textTab"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="bottom|center" />
use this code for any item you want to give it ripple effect.
copy this code into a new XML file in the drawable folder. and set it as the background of any item you want ripple effect for.
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:color="#color/icons"
tools:targetApi="lollipop">
<item android:drawable="?attr/colorPrimaryDark" />
</ripple
This should work
mTabs.setTabRippleColor(getResources().getColorStateList(R.color.colorPrimaryDark));
Related
I have a 9 patch drawable which I want to use as a background on a view. I want the view to show a ripple effect that follows the outline of a 9 patch when the view is clicked. Here's my activity, layout, and drawable code.
MainActivity.kt:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val click = findViewById<ConstraintLayout>(R.id.container)
click.setOnClickListener { Toast.makeText(this, "Clicked", Toast.LENGTH_SHORT).show() }
}
}
activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.antonc.testapp.MainActivity">
<android.support.constraint.ConstraintLayout
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="8dp"
android:paddingStart="8dp"
android:paddingEnd="8dp"
android:paddingTop="16dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:background="#drawable/tooltip_background"
android:backgroundTint="#2681d8"
tools:layout_editor_absoluteX="8dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello test test !!!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintHorizontal_bias="0.0"
/>
</android.support.constraint.ConstraintLayout>
</android.support.constraint.ConstraintLayout>
tooltip_background.xml:
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="#33000000">
<item android:drawable="#drawable/tooltip_left_top"/>
<item android:id="#android:id/mask" android:drawable="#drawable/tooltip_left_top"/>
</ripple>
tooltip_left_top.9.png:
But when I click on it, the ripple drawable is very distorted, as if it's stretched to the view size without observing the stretch rules of 9 patch. How should I configure the ripple to make it be the same as the background?:
Update: I have reworked the answer to refine the issue. The following has been edited to reflect the changes.
TL;DR Do not use android:backgroundTint for ripple backgrounds based on nine-patch drawables at least for API 28. Set the tint in code.
This issue has something to do with the background tint. I will explain how I came to this conclusion by referring to the following video.
I will refer to the bubbles as view1 through view4 from top to bottom. I changed from your nine-patch to better see the patches since your nine-patch was mostly black.
View1, when click, shows the appropriate ripple effect. It has a ripple background but no background tint.
View2 is what you are seeing with your background - it is just messed up. This view has a background tint set in XML.
The height of view3 has been forced to the height of view1 to see how the ripple looks. As you can see, the ripple looks right for the height. It is the non-ripple background image that is distorted.
View4 is the same as view2 except that it has the tint for RippleDrawable added programmatically. As you can see, this view looks and behaves as it should.
Bottom line? Don't set the background tint for a nine-patch in XML. Set it in code. Is this a bug? Maybe.
Here is the support code for the video above.
activity_main.xml
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FFFFFFFF"
android:fillViewport="true"
android:orientation="vertical"
android:padding="16dp"
tools:context=".MainActivity">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
tools:context=".MainActivity">
<ImageView
android:id="#+id/imageView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:background="#drawable/bubble_background"
android:clickable="true" />
<ImageView
android:id="#+id/imageView2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:background="#drawable/bubble_background"
android:backgroundTint="#color/background_tint"
android:clickable="true" />
<ImageView
android:id="#+id/imageView3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:background="#drawable/bubble_background"
android:backgroundTint="#color/background_tint"
android:clickable="true" />
<ImageView
android:id="#+id/imageView4"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:background="#drawable/bubble_background"
android:clickable="true" />
</LinearLayout>
</ScrollView>
bubble_background.xml
<ripple
android:color="#33000000">
<item android:drawable="#drawable/ninepatch_bubble">
</item>
</ripple>
MainActivity.java
public class MainActivity extends AppCompatActivity {
private LinearLayout mLayout;
private ImageView mImageView1;
private ImageView mImageView2;
private ImageView mImageView3;
private ImageView mImageView4;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mLayout = findViewById(R.id.layout);
mImageView1 = findViewById(R.id.imageView1);
mImageView2 = findViewById(R.id.imageView2);
mImageView3 = findViewById(R.id.imageView3);
mImageView4 = findViewById(R.id.imageView4);
int bgTint = getResources().getColor(R.color.background_tint);
RippleDrawable rippleDrawable =(RippleDrawable) mImageView4.getBackground();
rippleDrawable.getDrawable(0).setTint(bgTint);
mImageView4.setBackground(rippleDrawable);
mLayout.post(new Runnable() {
#Override
public void run() {
mImageView3.getLayoutParams().height = mImageView1.getMeasuredHeight();
mLayout.requestLayout();
}
});
}
}
colors.xml
These were added to colors.xml:
<color name="background_tint">#2681d8</color>
<color name="ripple_tint">#33000000</color>
ninepatch_bubble.9.png
Try to use ripple effect like this:
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="#color/White">
<item android:drawable="#drawable/tooltip_left_top" />
<item android:id="#android:id/mask">
<color android:color="#color/your_tooltip_color_code" />
</item>
</ripple>
Update here if it works.
I've created code so that Fragment is added dynamically when I tap on a menu button. However I get the error:
No view found for id 0x7f0d009a (tech.glasgowneuro.attysecg:id/fragment_container2) for fragment XYPlotFragment{a75aa2e #0 id=0x7f0d009a}
I've been through all the other posts here and the std answer is that the Frame layout needs to be child of the main layout. I think I've done that right. Still no id is found.
activity_plot_window.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/mainlayout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/my_toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:elevation="4dp"
android:theme="#style/ThemeOverlay.AppCompat.ActionBar"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<tech.glasgowneuro.attysecg.InfoView
android:id="#+id/infoview"
title="Plot Window"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_marginBottom="10dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginTop="10dp" />
<tech.glasgowneuro.attysecg.RealtimePlotView
android:id="#+id/realtimeplotview"
title="Plot Window"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_marginBottom="10dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginTop="10dp" />
</RelativeLayout>
<FrameLayout
android:id="#+id/fragment_container2"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
</RelativeLayout><!-- </LinearLayout> -->
main JAVA code of the Activity:
public class AttysECG extends AppCompatActivity {
...
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
....
setContentView(R.layout.activity_plot_window);
Toolbar myToolbar = (Toolbar) findViewById(R.id.my_toolbar);
setSupportActionBar(myToolbar);
....
}
...
case R.id.showplot:
// Create a new Fragment to be placed in the activity layout
XYPlotFragment plotFragment = new XYPlotFragment();
// Add the fragment to the 'fragment_container' FrameLayout
getSupportFragmentManager().beginTransaction()
.add(R.id.fragment_container2, plotFragment).commit();
The question is why do I get this exception? If I do a findViewById(fragment_container2) then the result is null.
How can I get a valid id for the fragment_container2?
At this point the view is certainly inflated because I trigger this crash long after the app has been started.
I've figured it out. Android studio created two "activity_plot_window.xml" files. One has the suffix _v21 so that there are two versions for the older APIs and the newer ones. It's explained here:
https://developer.android.com/training/material/compatibility.html
I've added the Framelayout to the _v21 file and now it works. See the screenshot. It's very easy to oversee when not expanded (just a grey (2)).
You need to find it through FragmentManager:
getSupportFragmentManager().findFragmentById(R.id.fragment_container2);
I followed the procedure explained on the link bellow but for some reason the switch is never displayed. I changed the visibility to match my app namespace as suggested in other threads to no avail. The procedure works fine if I try adding Icon's or regular buttons.
Thanks a lot.
I'm running it on a Nexus 4 with Android 4.4.4
How to add a switch to android action bar?
Here is my current xml contents.
/menu/main.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context="com.example.testapp.MainActivity" >
<item
android:id="#+id/myswitch"
android:title=""
app:showAsAction="always"
android:actionLayout="#layout/switch_layout"
/>
</menu>
/layout/switch_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<Switch
android:id="#+id/switchForActionBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="" />
</LinearLayout>
Ok, So I finally found something that works for me.
I created a layout file :/layout/text_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
> <!-- android:layout_height="50dp" -->
<Switch
android:id="#+id/switchForActionBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
/>
</RelativeLayout>
Then on my MainActivity.java
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ActionBar mActionBar = getActionBar();
LayoutInflater mInflater = LayoutInflater.from(this);
View mCustomView = mInflater.inflate(R.layout.test_layout, null);
mActionBar.setCustomView(mCustomView);
mActionBar.setDisplayShowCustomEnabled(true);
}
BOOOMMM, there you go.
It's impressive how simple things can be so complicated on Android sometimes.
Thanks for the suggestions.
currently I'm trying to implement the FragmentTabHost for my project. I'm still new on this fragments but I found it very great in terms of reusing the layouts, etc which is why I wanted to push myself further on to it. Now I read the tutorials on how to create a Tabs with fragment and I came on this tutorial:
http://maxalley.wordpress.com/2013/05/18/android-creating-a-tab-layout-with-fragmenttabhost-and-fragments/
Now this works just fine, except that the tabWidget is on top of my layout where I wanted it to be on bottom. I find that I need to setup the tabWidget after all the tabs has been initialized so I tried to add these codes:
mTabWidget = (TabWidget) findViewById(android.R.id.tabs);
mTabWidget.setBackgroundColor(Color.WHITE);
mTabWidget.setShowDividers(LinearLayout.SHOW_DIVIDER_NONE);
mTabWidget.setGravity(Gravity.BOTTOM);
Now this one already eliminated the divider and changes the color but obviously won't put my Widget on the bottom part of my layout. Now how would I do that?
I also tried to edit the Tabhost xml and just put the TabWidget after the FrameLayout but nothing happens. here's the xml:
<android.support.v4.app.FragmentTabHost
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#android:id/tabhost"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<FrameLayout
android:id="#+id/tabFrameLayout"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
<TabWidget
android:id="#android:id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0"
android:orientation="horizontal"
/>
</LinearLayout>
</android.support.v4.app.FragmentTabHost>
I have refer this link github example
This will be your layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<FrameLayout
android:id="#+id/realtabcontent"
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="1" />
<android.support.v4.app.FragmentTabHost
android:id="#android:id/tabhost"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<FrameLayout
android:id="#android:id/tabcontent"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="0" />
</android.support.v4.app.FragmentTabHost>
</LinearLayout>
For your custom Tabs :
mTabHost.addTab(setIndicator(mTabHost.newTabSpec("Tab1"),
R.drawable.image1),
public TabSpec setIndicator(Context ctx,TabSpec spec, int resid) {
// TODO Auto-generated method stub
View v = LayoutInflater.from(ctx).inflate(R.layout.tabs_text, null);
v.setBackgroundResource(resid);
TextView text = (TextView) v.findViewById(R.id.tab_title);
text.setText(spec.getTag());
return spec.setIndicator(v);
}
Edit
//To set drawable to your perticular TAB
mTabHost.getTabWidget().getChildAt(0).setBackgroundResource(R.drawable.tab_login);
end Edit
If you want to add drawable (selector):
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/tab_compose_h" android:state_selected="true"/>
<item android:drawable="#drawable/tab_compose_h" android:state_pressed="true"/>
<item android:drawable="#drawable/tab_compose"/>
</selector>
Image as seen in ICS
Where as when run in Gingerbread
XML code for the fragment
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="#drawable/background"
android:id="#+id/homelayout" >
<ImageView
android:id="#+id/homepageLogo"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="#drawable/background"
android:alpha="255"
android:scaleType="fitXY" />
</LinearLayout>
Any reason for such strange behavior?
try changing
android:layout_width="match_parent"
android:layout_height="match_parent"
to
android:layout_width="wrap_content"
android:layout_height="wrap_content"
in your ImageView. I don't know how you use your XML, but by the looks of it you might also want to change te same parameters in the LinearLayout to "wrap_content". Now you are telling the ImageView to (probably) fill the whole area.
// Alex
The problem is observed only when you dynamically request for the actionbar from the code.
getWindow().requestFeature(Window.FEATURE_ACTION_BAR);
If you do it using styles, this problem is not seen.