i have a problem with tab bar.
I styled tab bar with three tab, each with an icon, the problem is that the tab bar becomes scrollable and I would like to fixed.
I tried to put this in the style of the tab bar
<style parent="#android:style/Widget.Holo.Light.ActionBar.Solid" name="ActionBar.Solid.Customactionbar">
<item name="android:background">#color/actionbar_background</item>
<item name="android:showDividers">none</item>
<item name="android:gravity">center</item>
<item name="android:scrollHorizontally">false</item>
<item name="android:scrollbars">none</item>
</style>
<style parent="#android:style/Widget.Holo.Light.ActionBar.TabView" name="ActionBarTabStyle.Customactionbar">
<item name="android:background">#color/actionbar_background</item>
<item name="android:scrollHorizontally">false</item>
<item name="android:scrollbars">none</item>
</style>
and in activity_main
<TabHost
android:id="#android:id/tabhost"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:isScrollContainer="false">>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TabWidget
android:id="#android:id/tabs"
android:layout_width="match_parent"
android:layout_height="48dp"
android:showDividers="none"
android:gravity="center"
android:isScrollContainer="false">
</TabWidget>
but nothing.
Can anyone help me?
Thank you!
If you use ViewPager - you need
CustomViewPager.java
public class CustomViewPager extends ViewPager {
private boolean isPagingEnabled = true;
public CustomViewPager(Context context) {
super(context);
}
public CustomViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
return this.isPagingEnabled && super.onTouchEvent(event);
}
#Override
public boolean onInterceptTouchEvent(MotionEvent event) {
return this.isPagingEnabled && super.onInterceptTouchEvent(event);
}
public void setPagingEnabled(boolean b) {
this.isPagingEnabled = b;
}
}
replace your ViewPager
from
<android.support.v4.view.ViewPager
android:id="#+id/viewpager"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
/>
to
<CustomViewPager
android:id="#+id/viewpager"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
/>
in your Activity:
CustomViewPager mViewPager = (CustomViewPager) findViewById(R.id.viewpager);
mViewPager.setPagingEnabled(false);
Related
I have never seen a bug as weird as that before, I'm linking a viewpager with a tablayout, inside the viewpager there are three fragments.
Two of the fragments (let's say fragment 1 & 3) have a button inside them and their colours are both set to "pink". When I first load the app, it shows fragment 1, the button is pink at that moment, however, whenever I switch to fragment 3, the background color of the button is changed to "white" and other attributes of the button stay the same.
This won't happen if I switch to fragment 2. However, if I switch to fragment 3 once, both fragments 1 & 3's button have white background for the rest of the lifetime.
Can someone tell me what's happening here or what could cause this? I'm not changing the style of the buttons in Java files at all.
MainActivity.java
public class MainActivity extends AppCompatActivity {
private ActivityMainBinding binding;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
setUpWithViewPager(binding.viewPager);
// setupWithViewPager is a built-in method for TabLayout, setting up this TabLayout with a ViewPager
// The TabLayout will be automatically populated from the PagerAdapter's page titles. By doing that,
// when the user tabs on the tab, the appropriate fragment will be shown in the ViewPager
// TabLayout provides a horizontal layout to display tabs.
// Without this line you can still swipe left/right to see all the pages, just cannot tab on the
// tab to switch pages
binding.tabLayout.setupWithViewPager(binding.viewPager);
// This method sets the toolbar as the app bar for the activity
setSupportActionBar(binding.toolbar);
// change the fab icon when the page is changed
binding.viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
changeFabIcon(position);
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
}
private void setUpWithViewPager(ViewPager viewPager) {
// An inner class defined in MainActivity
SectionsPagerAdapter adapter = new SectionsPagerAdapter(getSupportFragmentManager());
adapter.addFragment(new ChatsFragment(), "Chats");
adapter.addFragment(new StatusFragment(), "Status");
adapter.addFragment(new CallsFragment(), "Calls");
// We need 3 fragments
viewPager.setAdapter(adapter);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// getMenuInflater is used to instantiate menu XML files into Menu objects.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(#NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_search: Toast.makeText(this, "Action Search", Toast.LENGTH_SHORT).show(); break;
case R.id.menu_more: Toast.makeText(this, "Action More", Toast.LENGTH_SHORT).show(); break;
}
return super.onOptionsItemSelected(item);
}
private void changeFabIcon(final int index) {
binding.fabAction.hide();
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
switch (index) {
case 0: binding.fabAction.setImageDrawable(getDrawable(R.drawable.ic_baseline_chat_24)); break;
case 1: binding.fabAction.setImageDrawable(getDrawable(R.drawable.ic_baseline_camera_alt_24)); break;
case 2: binding.fabAction.setImageDrawable(getDrawable(R.drawable.ic_baseline_call_24)); break;
}
binding.fabAction.show();
}
}, 400);
}
private static class SectionsPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
public SectionsPagerAdapter(#NonNull FragmentManager fm) {
super(fm);
}
#NonNull
#Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
#Nullable
#Override
public CharSequence getPageTitle(int position) {
return mFragmentTitleList.get(position);
}
#Override
public int getCount() {
return mFragmentList.size();
}
public void addFragment(Fragment fragment, String title) {
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<layout
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">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".view.MainActivity">
<com.google.android.material.appbar.AppBarLayout
android:id="#+id/app_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/colorPrimary">
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="50dp"
app:titleTextColor="#android:color/white"
app:title="PepperChat"/>
</com.google.android.material.appbar.AppBarLayout>
<com.google.android.material.tabs.TabLayout
android:id="#+id/tab_layout"
android:layout_below="#+id/app_bar"
android:layout_width="match_parent"
android:layout_height="50dp"
app:tabBackground="#color/colorPrimary"
app:tabGravity="fill"
app:tabIndicator="#color/colorPrimary"
app:tabIndicatorHeight="3dp"
app:tabIndicatorColor="#android:color/white"
app:tabSelectedTextColor="#android:color/white"
app:tabTextColor="#android:color/white">
</com.google.android.material.tabs.TabLayout>
<androidx.viewpager.widget.ViewPager
android:id="#+id/view_pager"
android:layout_below="#id/tab_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="visible"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="#+id/fab_action"
android:src="#android:drawable/stat_notify_chat"
android:tint="#android:color/white"
app:backgroundTint="#color/colorPrimary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentEnd="true"
android:layout_margin="15dp"/>
</RelativeLayout>
</layout>
fragment_calls.xml
<?xml version="1.0" encoding="utf-8"?>
<layout>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".menu.CallsFragment">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<LinearLayout
android:id="#+id/ln_invite"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:layout_marginTop="30dp"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Invite your friends"
android:textSize="25dp"
android:textColor="#android:color/black"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:layout_marginBottom="20dp"
android:textColor="#color/colorPrimary"
android:gravity="center_horizontal"
android:text="Name of your contact are using PepperChat.\nUse the bottom below to invite them."/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/colorPrimary"
android:textColor="#android:color/black"
android:layout_marginStart="30dp"
android:layout_marginEnd="30dp"
android:text="Invite a friend"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:layout_marginBottom="20dp"
android:gravity="center_horizontal"
android:text="Chat with your friends who are using PepperChat on iphone,\nAndroid or KaiOS phone"/>
</LinearLayout>
</FrameLayout>
</layout>
fragment_chats.xml
<?xml version="1.0" encoding="utf-8"?>
<layout>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".menu.ChatsFragment">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_height="match_parent"
android:layout_width="match_parent"/>
<LinearLayout
android:id="#+id/ln_invite"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:layout_marginTop="30dp"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Invite your friends"
android:textSize="25dp"
android:textColor="#android:color/black"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:layout_marginBottom="20dp"
android:textColor="#color/colorPrimary"
android:gravity="center_horizontal"
android:text="Name of your contact are using PepperChat.\nUse the bottom below to invite them."/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/colorPrimary"
android:textColor="#android:color/black"
android:layout_marginStart="30dp"
android:layout_marginEnd="30dp"
android:text="Invite a friend"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:layout_marginBottom="20dp"
android:gravity="center_horizontal"
android:text="Chat with your friends who are using PepperChat on iphone,\nAndroid or KaiOS phone"/>
</LinearLayout>
</FrameLayout>
</layout>
After adding the following line in both of the xml files, the button appears normally, not sure why though, can someone explain what happened? (is that something related to the theme I'm using?)
android:backgroundTint="#color/colorPrimary"
and my theme is
<style name="Theme.PepperChat" parent="Theme.AppCompat.Light.NoActionBar">
<!-- Primary brand color. -->
<item name="colorPrimary">#color/colorPrimary</item>
<item name="colorPrimaryDark">#color/colorPrimaryDark</item>
<item name="colorAccent">#color/colorAccent</item>
</style>
if I change the parent to Theme.MaterialComponent.Light.NoActionBar, then the app works fine without adding backgroundTint.
Again, would like some explanations on why this happens.
i have a tablayout scrollable, but when i choose one tabitem, the scrollable is stopped, i need the TabItem in the center when i choose any. Thank you.
<com.google.android.material.tabs.TabLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabSelectedTextColor="#color/colorPrimary">
<com.google.android.material.tabs.TabItem
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Calle Mármol complejo 23" />
<com.google.android.material.tabs.TabItem
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Calle Mármol complejo 23" />
<FrameLayout
android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
now the java file, just for go to the tabitem
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem menuItem) {
boolean fragmentTransaction = false;
Fragment fragment = null;
switch (menuItem.getItemId()) {
case R.id.nav_home:
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,
new HomeFragment()).commit();
titleToolbar = getResources().getString(R.string.Menu_Home);
fragmentTransaction = true;
getSupportActionBar().setTitle(titleToolbar);
break;
case R.id.nav_receipts:
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,
new ReceiptsFragment()).commit();
titleToolbar = getResources().getString(R.string.Menu_Receipts);
fragmentTransaction = true;
getSupportActionBar().setTitle(titleToolbar);
break;
XML:
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.google.android.material.tabs.TabLayout
android:id="#+id/tabs"
style="#style/TabStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:elevation="5dp"
app:tabMode="scrollable" />
<androidx.viewpager.widget.ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</androidx.appcompat.widget.LinearLayoutCompat>
Styles
<style name="TabStyle" parent="Widget.Design.TabLayout">
<item name="android:background">#color/colorPrimary</item>
<item name="tabTextAppearance">#style/TabTextStyle</item>
<item name="tabIndicatorColor">#color/white</item>
<item name="tabTextColor">#color/red_light</item>
<item name="tabSelectedTextColor">#color/white</item>
</style>
<style name="TabTextStyle" parent="TextAppearance.AppCompat.Button">
<item name="android:textSize">#dimen/_10sdp</item>
</style>
Java
public class MainActivity extends AppCompatActivity {
private SampleAdapter adapter;
private TabLayout tabs;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ViewPager pager=(ViewPager)findViewById(R.id.pager);
adapter=new SampleAdapter(this, getSupportFragmentManager());
pager.setAdapter(adapter);
tabs=(TabLayout)findViewById(R.id.tabs);
tabs.setupWithViewPager(pager);
tabs.setTabMode(TabLayout.MODE_SCROLLABLE);
}
}
assign your fragment in Adapter according to tabItem
I am trying to change an icon in the actionbar, but I can not get it work. If I send to the log the getIcon().toString(), It seems that the icon is modified, but the actionbar is not updated.
This is the main activity layout:
<?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=".MainActivity"
tools:layout_editor_absoluteY="81dp">
<android.support.v7.widget.Toolbar
android:id="#+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:elevation="4dp"
android:minHeight="?attr/actionBarSize"
android:theme="#style/AppTheme.AppBarOverlay"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:popupTheme="#style/AppTheme">
</android.support.v7.widget.Toolbar>
The menu xml file:
<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=".MainActivity">
<item
android:id="#+id/action_settings"
android:title="#string/action_settings"
android:orderInCategory="100"
app:showAsAction="never" />
<item
android:id="#+id/about"
android:title="#string/about"
android:orderInCategory="110"
app:showAsAction="never" />
<item
android:id="#+id/connect"
android:title="Connect"
android:icon="#drawable/ic_play"
android:orderInCategory="130"
app:showAsAction="always" />
<item
android:id="#+id/testin"
android:title="Test_in"
android:icon="#drawable/ic_testin"
android:orderInCategory="120"
app:showAsAction="always" />
And the main activity code:
//Menu Items
MenuItem testinMenu, connectMenu;
Menu actionMenu;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Action Bar
toolbar = findViewById( R.id.appbar);
setSupportActionBar( toolbar);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menumain, menu);
actionMenu = menu;
connectMenu = (MenuItem) menu.findItem(R.id.connect);
testinMenu = (MenuItem) menu.findItem(R.id.testin);
return true;
}
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.connect: {
connectMenu.setIcon( R.drawable.ic_stop);
invalidateOptionsMenu();
if( isRainbowConnected == false) {
connect();
} else
disconnect();
break;
}
case R.id.testin: {
if( isRainbowConnected == true)
sendTestIn();
break;
}
// case blocks for other MenuItems (if any)
}
return true;
}
I have tried everything, but nothing seems to work.
Thanks in advance!
Hello I am trying to add a ripple effect onClick method for View, but this one no working. All my items having an ID, but I don't know how to call it
Here is a code.
#Override
public void onClick(View v) {
int[] attrs = new int[]{R.attr.selectableItemBackground};
TypedArray typedArray = getActivity().obtainStyledAttributes(attrs);
int backgroundResource = typedArray.getResourceId(0, 0);
v.setBackgroundResource(backgroundResource);
switch (v.getId()) {
case ACTION_PLAY_ID:
Log.d(MainActivity.TAG, getString(R.string.detail_action_play));
v.setBackgroundResource(backgroundResource);
Intent intent = new Intent(getActivity(), PlayerActivity.class);
intent.putExtra(Video.VIDEO_TAG, videoModel);
startActivity(intent);
break;
case ACTION_BOOKMARK_ID:
if (bookmarked) {
v.setBackgroundResource(backgroundResource);
deleteFromBookmarks();
((ImageView) v).setImageDrawable(res.getDrawable(R.drawable.star_outline));
} else {
v.setBackgroundResource(backgroundResource);
addToBookmarks();
((ImageView) v).setImageDrawable(res.getDrawable(R.drawable.star));
}
break;
case ACTION_REMINDER_ID:
if (!isReminderSet) {
createReminderDialog((ImageView) v);
} else {
cancelReminder(liveTvProgram.getProgramId());
((ImageView) v).setImageDrawable(res.getDrawable(R.drawable.alarm));
}
break;
}
}
For Lubomir
i have something like this but not working too:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle
savedInstanceState) {
View view = inflater.inflate(R.layout.item_detail, container, false);
ButterKnife.bind(this, view);
View myView = view.findViewById(R.id.actions_container);
int[] attrs = new int[]{R.attr.selectableItemBackground};
TypedArray typedArray = getActivity().obtainStyledAttributes(attrs);
int backgroundResource = typedArray.getResourceId(0, 0);
myView.setBackgroundResource(backgroundResource);
loadImage();
init();
return view;
}
ImageViews(actionbuttons) is creating in java for LinearLayout actions_container
<?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="match_parent">
<ImageView
android:id="#+id/header_image"
android:layout_width="250dp"
android:layout_height="250dp"
android:layout_alignParentLeft="true"
android:layout_marginLeft="10dp"
android:layout_marginStart="10dp"
android:layout_marginTop="#dimen/detail_image_1_state"
android:elevation="8dp"/>
<RelativeLayout
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="#dimen/detail_bottom_margin"
android:layout_marginTop="#dimen/detail_top_margin"
android:background="#color/primary_color">
<LinearLayout
android:id="#+id/actions_container"
android:layout_width="match_parent"
android:layout_height="#dimen/detail_actions_height"
android:layout_alignParentTop="true"
android:background="#drawable/ripple_effect_image"
android:elevation="2dp"
android:orientation="horizontal"
android:paddingLeft="300dp"
android:paddingStart="300dp"/>
<LinearLayout
android:id="#+id/content_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/actions_container"
android:orientation="vertical"
android:paddingLeft="300dp"
android:paddingStart="300dp">
<TextView
android:id="#+id/title"
style="#style/TextTitleStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:id="#+id/subtitle"
style="#style/TextSubtitleStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"/>
<TextView
android:id="#+id/duration"
style="#style/TextSubtitleStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:id="#+id/season"
style="#style/TextDescriptionStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"/>
<TextView
android:id="#+id/episode"
style="#style/TextDescriptionStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"/>
<TextView
android:id="#+id/description"
style="#style/TextDescriptionStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLines="7"/>
</LinearLayout>
<FrameLayout
android:id="#+id/recommended_frame"
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_alignParentBottom="true">
<android.support.v17.leanback.widget.HorizontalGridView
android:id="#+id/recommendation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clipChildren="false"
android:clipToPadding="false"
android:paddingLeft="10dp"
android:paddingRight="10dp"/>
</FrameLayout>
<TextView
android:id="#+id/recommended_text"
style="#style/TextHeaderStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="#id/recommended_frame"
android:text="#string/related_programs"/>
</RelativeLayout>
</RelativeLayout>
Also my xml ripple effect file is like:
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="#color/dark_primary_color">
<item>
<color android:color="#color/dark_primary_color" />
</item>
<item android:id="#android:id/mask">
<shape android:shape="rectangle">
<solid android:color="?android:colorAccent" />
</shape>
</item>
</ripple>
Clickable Views
In general, ripple effect for regular buttons will work by default in API 21 and for other touchable views, it can be achieved by specifying
android:background="?android:attr/selectableItemBackground"
In code:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.your_layout);
View myView = findViewById(R.id.myView);
int[] attrs = new int[]{R.attr.selectableItemBackground};
TypedArray typedArray = getActivity().obtainStyledAttributes(attrs);
int backgroundResource = typedArray.getResourceId(0, 0);
myView.setBackgroundResource(backgroundResource);
}
As stated in Lubomir Babev's answer, adding android:background="?android:attr/selectableItemBackground" does the trick.
However, if your view already has a background, you can use the same on the android:foreground attribute instead:
android:background="#color/anyColor"
android:foreground="?android:attr/selectableItemBackground"
android:foreground is only supported by API 23+ though.
create ripple background
view_background.xml
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="#color/blue" >
<item android:drawable="#drawable/view_normal">
</item>
</ripple>
view_noraml.xml //this is how you view appears in normal
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<corners
android:radius="#dimen/button_corner"/>
<solid
android:color="#android:color/transparent"/>
<stroke
android:width="0.5dp"
android:color="#color/white"/>
</shape>
now set the view_background to your view
example
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="120dp"
android:foreground="#drawable/view_background"
android:clickable="true"
android:focusable="true"
>
<ImageView
android:id="#+id/grid_item_imageView"
android:layout_width="match_parent"
android:layout_height="120dp"
android:layout_gravity="center"
android:scaleType="centerInside"
/>
</FrameLayout>
I know this is a pretty old thread but just in case the above answers didn't work, I'd recommend you to try the below code as it worked for me:
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:background="?android:attr/selectableItemBackground"
android:clickable="true"
android:focusable="true"
android:layout_width="match_parent"
android:layout_height="wrap_content">
The key thing to notice are the clickable and focusable.
The solution for this is simple easy in my side.
Here is ripple effect:
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="#BFB3F7">
<item android:id="#android:id/mask">
<shape android:shape="oval">
<solid android:color="#color/button_background_color" />
</shape>
</item>
</ripple>
and next on the class i need to search function
setBackground
Then i need declare a drawable item to it. something like this:
#Override
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus) {
v.setBackground(res.getDrawable(R.drawable.ripple_effect_for_buttons));
scrollContainer(false);
} else {
v.setBackground(null);
if (recommendation.getFocusedChild() != null) {
scrollContainer(true);
}
}
}
And YUPII its working
You can add:
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="true"
android:background="#drawable/ripple"/>
In Kotlin it could be easily done with an extension functions.
fun TypedArray.use(block: TypedArray.() -> Unit) {
try {
block()
} finally {
this.recycle()
}
}
fun Context.getStyledAttributes(#StyleableRes attrs: IntArray, block: TypedArray.() -> Unit) =
this.obtainStyledAttributes(attrs).use(block)
fun View.setClickableRipple() {
val attrs = intArrayOf(R.attr.selectableItemBackground)
context.getStyledAttributes(attrs) {
val backgroundResource = getResourceId(0, 0)
setBackgroundResource(backgroundResource)
}
}
I created a custom component in Android Studio and it is not rendering in edit mode, but it shows when I run in the emulator.
I created snippetLabel.java inside a module named custom.
public class SnippetLabel extends LinearLayout {
TextView label;
TextView content;
public SnippetLabel(Context context, AttributeSet attrs) {
super(context, attrs);
this.setOrientation(VERTICAL);
LayoutParams labelLayoutParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
labelLayoutParams.setMargins(0, 0, 0, (int) context.getResources().getDimension(R.dimen.snippetabel_label) );
LayoutParams contentLayoutParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
label = new TextView(context, attrs);
label.setTextAppearance(context, R.style.GridSystem_Forms_SnippetLabelLabel);
addView(label, labelLayoutParams);
content = new TextView(context, attrs);
content.setTextAppearance(context, R.style.GridSystem_Forms_SnippetLabelContent);
addView(content, contentLayoutParams);
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.snippet_label);
CharSequence sl = a.getString(R.styleable.snippet_label_label);
CharSequence sc = a.getString(R.styleable.snippet_label_content);
if (sl != null) { label.setText(sl); }
if (sc != null) { content.setText(sc); }
a.recycle();
}
public void setContentText(String s){
content.setText(s);
}
public void setLabelText(String s){
label.setText(s);
}
public String getContentText(){
return (String) content.getText();
}
}
SnippetLabel.java
<resources>
<declare-styleable name="snippet_label">
<attr name="label" format="string" />
<attr name="content" format="string" />
</declare-styleable>
</resources>
Attrs.xml
<style name="GridSystem.Forms.SnippetLabel">
<item name="android:layout_width">0dp</item>
<item name="android:layout_height">wrap_content</item>
</style>
<style name="GridSystem.Forms.SnippetLabelLabel">
<item name="android:layout_width">wrap_content</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:layout_marginBottom">#dimen/snippetabel_label</item>
<item name="android:textStyle">bold</item>
<item name="android:textColor">#color/SnippetLabelLabel</item>
<item name="android:textAppearance">?android:attr/textAppearanceSmall</item>
</style>
<style name="GridSystem.Forms.SnippetLabelContent">
<item name="android:layout_width">wrap_content</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:textColor">#color/SnippetLabelContent</item>
<item name="android:textAppearance">?android:attr/textAppearanceSmall</item>
</style>
style.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/currentRelativeLayout"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ScrollView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/toolbar">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin">
<LinearLayout
android:id="#+id/linearLayoutForm"
style="#style/GridSystem.Panel">
<TextView
style="#style/GridSystem.Title"
android:text="Resultado" />
<LinearLayout
android:id="#+id/secao_entregue_na_grafica"
style="#style/GridSystem.Row">
<view
android:id="#+id/view"
class="br.gov.prodemge.comum.ui.snippets.SnippetLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="100" />
<br.gov.prodemge.comum.ui.snippets.SnippetLabel
android:id="#+id/campo_entregue_na_grafica"
style="#style/GridSystem.Forms.SnippetLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="100"
app:content="#"
app:label="Entregue na Gráfica:" />
</LinearLayout>
<LinearLayout
android:id="#+id/secao_prazo"
style="#style/GridSystem.Row">
<br.gov.prodemge.comum.ui.snippets.SnippetLabel
android:id="#+id/campo_situacao"
style="#style/GridSystem.Forms.SnippetLabel"
android:layout_weight="50"
app:content="#"
app:label="Situação:" />
<br.gov.prodemge.comum.ui.snippets.SnippetLabel
android:id="#+id/campo_prazo"
style="#style/GridSystem.Forms.SnippetLabel"
android:layout_weight="50"
app:content="#"
app:label="Prazo:" />
</LinearLayout>
<LinearLayout
android:id="#+id/secao_mensagem_status"
style="#style/GridSystem.Row">
<br.gov.prodemge.comum.ui.snippets.SnippetLabel
android:id="#+id/campo_mensagem_status"
style="#style/GridSystem.Forms.SnippetLabel"
android:layout_weight="100"
app:content="#"
app:label="[Mensagem de Status]:" />
</LinearLayout>
<LinearLayout
android:id="#+id/secao_ar_correio"
style="#style/GridSystem.Row">
<br.gov.prodemge.comum.ui.snippets.SnippetLabel
android:id="#+id/campo_ar_correio"
style="#style/GridSystem.Forms.SnippetLabel"
android:layout_weight="100"
app:content="#"
app:label="AR Correio:" />
</LinearLayout>
<LinearLayout
android:id="#+id/secao_situacao_entrega"
style="#style/GridSystem.Row">
<br.gov.prodemge.comum.ui.snippets.SnippetLabel
android:id="#+id/campo_situacao_entrega"
style="#style/GridSystem.Forms.SnippetLabel"
android:layout_weight="100"
app:content="#"
app:label="Situação da Entrega:" />
</LinearLayout>
<LinearLayout
android:id="#+id/secao_motivo_rejeicao"
style="#style/GridSystem.Row">
<br.gov.prodemge.comum.ui.snippets.SnippetLabel
android:id="#+id/campo_motivo_rejeicao"
style="#style/GridSystem.Forms.SnippetLabel"
android:layout_weight="100"
app:content="#"
app:label="Motivo Rejeição:" />
</LinearLayout>
<LinearLayout
android:id="#+id/secao_acao"
style="#style/GridSystem.Row">
<br.gov.prodemge.comum.ui.snippets.SnippetLabel
android:id="#+id/campo_acao"
style="#style/GridSystem.Forms.SnippetLabel"
android:layout_weight="100"
app:content="#"
app:label="Ação:" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
</ScrollView>
layout.xml
Your custom view class has to implement more constuctors, the views are instantiated differently in Preview and on the device/emulator. A common pattern is to move your initialization code to some method and call it from construstors. See example
public class SnippetLabel extends LinearLayout {
public SnippetLabel(Context context) {
super(context);
init();
}
public SnippetLabel(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public SnippetLabel(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
this.setOrientation(VERTICAL);
...
}
}
There is another thing to keep in mind, complementing on #Lamorak answer:
If your component depends on external data, such as a status from a service, data from shared preferences, etc. you have to surrund your init() method with a try-catch.
On design mode you don't have access to external data, so any problem that prevents the constructor from being completed, your component will not show.