Reputation: 2305
I want use TabLayout
in my application for use fragment
and ViewPager
.
but I want disable click on TabLayout
to switch between fragment
, just swipe to switch between fragmenst
.
I write below codes, but not work me and when click on TabLayout
items, go to that fragment
!
MainActivity XML :
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:text="@string/app_namefull"
android:textSize="23sp" />
</android.support.v7.widget.Toolbar>
<android.support.design.widget.TabLayout
android:id="@+id/tabs"
android:layout_width="match_parent"
android:layout_height="72dp"
app:tabGravity="fill"
app:tabIndicatorColor="@color/white"
app:tabMode="fixed" />
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
</android.support.design.widget.CoordinatorLayout>
MainActivity java:
public class Main_Page extends AppCompatActivity {
private CollapsingToolbarLayout mCollapsingToolbarLayout;
private Toolbar toolbar;
private TabLayout tabLayout;
private ViewPager viewPager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main__page);
mCollapsingToolbarLayout = (CollapsingToolbarLayout) findViewById(R.id.collapsing_toolbar_layout);
//mCollapsingToolbarLayout.setTitle(getResources().getString(R.string.app_name));
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
//getSupportActionBar().setDisplayHomeAsUpEnabled(true);
viewPager = (ViewPager) findViewById(R.id.viewpager);
setupViewPager(viewPager);
tabLayout = (TabLayout) findViewById(R.id.tabs);
LinearLayout tabStrip = ((LinearLayout)tabLayout.getChildAt(0));
for(int i = 0; i < tabStrip.getChildCount(); i++) {
tabStrip.getChildAt(i).setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
return true;
}
});
}
tabLayout.setupWithViewPager(viewPager);
setupTabIcons();
}
/**
* Adding custom view to tab
*/
private void setupTabIcons() {
TextView tabOne = (TextView) LayoutInflater.from(this).inflate(R.layout.custom_tab, null);
tabOne.setText(R.string.free_fragment_title);
tabOne.setCompoundDrawablesWithIntrinsicBounds(0, R.drawable.ic_download_image, 0, 0);
tabLayout.getTabAt(0).setCustomView(tabOne);
TextView tabTwo = (TextView) LayoutInflater.from(this).inflate(R.layout.custom_tab, null);
tabTwo.setText(R.string.paid_fragment_title);
tabTwo.setCompoundDrawablesWithIntrinsicBounds(0, R.drawable.ic_paid_download_image, 0, 0);
tabLayout.getTabAt(1).setCustomView(tabTwo);
TextView tabThree = (TextView) LayoutInflater.from(this).inflate(R.layout.custom_tab, null);
tabThree.setText(R.string.pdf_fragment_title);
tabThree.setCompoundDrawablesWithIntrinsicBounds(0, R.drawable.ic_pdf_icon, 0, 0);
tabLayout.getTabAt(2).setCustomView(tabThree);
}
/**
* Adding fragments to ViewPager
* @param viewPager
*/
private void setupViewPager(ViewPager viewPager) {
ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
adapter.addFrag(new free_fragment(), "رایگان ها");
adapter.addFrag(new paid_fragment(), "پرداختی ها");
adapter.addFrag(new pdf_fragment(), "مقالات");
viewPager.setAdapter(adapter);
}
class ViewPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
public ViewPagerAdapter(FragmentManager manager) {
super(manager);
}
@Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
@Override
public int getCount() {
return mFragmentList.size();
}
public void addFrag(Fragment fragment, String title) {
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
@Override
public CharSequence getPageTitle(int position) {
return mFragmentTitleList.get(position);
}
}
}
for disable click on TabLayout
I use this code:
LinearLayout tabStrip = ((LinearLayout)tabLayout.getChildAt(0));
for(int i = 0; i < tabStrip.getChildCount(); i++) {
tabStrip.getChildAt(i).setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
return true;
}
});
}
How can I solve this problem? Thanks all <3
Upvotes: 39
Views: 34032
Reputation: 19966
For ViewPager2 (minimum v1.1.0) you can accomplish this in the TabLayoutMediator
.
new TabLayoutMediator(tabLayout, pager,
(tab, position) -> {
tab.view.setClickable(false);
}
).attach();
And in build.gradle
:
com.google.android.material:material:1.1.0-rc02
Upvotes: 43
Reputation: 1689
No need to use a Linear Layout, you could just add this on the activity:
private void setUntouchableTab () {
tablayout.setupWithViewPager(viewpager, true);
tablayout.clearOnTabSelectedListeners();
for (View v : tablayout.getTouchables()) {
v.setEnabled(false);
}
}
Upvotes: 17
Reputation: 797
This is what worked for me:
class LockableTabLayout : TabLayout {
var swipeable: Boolean = true
constructor(context: Context) : super(context)
constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
override fun onInterceptTouchEvent(event: MotionEvent): Boolean = !swipeable
}
Upvotes: 4
Reputation: 1693
touchable array list will solve this issue.
declare the activity
var touchableList: ArrayList<View>? = ArrayList()
disable all tab
touchableList = tabLayout?.touchables
touchableList?.forEach { it.isEnabled = false }
Enable the tab
touchableList?.get(0)?.isEnabled = true
Upvotes: 24
Reputation: 1268
The above answer here, disabled the tab item click when you already finish populated your tab item or already defined the tabitem on xmls.
e.g:
<android.support.design.widget.TabLayout
android:id="@+id/tabla_quiz_navigation"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.design.widget.TabItem
android:layout_width="wrap_content"
android:text="1"
android:layout_height="wrap_content"/>
<android.support.design.widget.TabItem
android:layout_width="wrap_content"
android:text="2"
android:layout_height="wrap_content"/>
<android.support.design.widget.TabItem
android:layout_width="wrap_content"
android:text="3"
android:layout_height="wrap_content"/>
</android.support.design.widget.TabLayout>
But, if you've different cases, when using Observable data or dynamic tabitem. e.g:
// QuizFragment.kt
quizListLive.observe(this@QuizFragment, Observer { quizList ->
quizList?.takeIf { list -> list.isNotEmpty() }?.let {
// this is where new fragment added
it.forEachIndexed { j, quiz ->
mViewPagerAdapter?.addFragment(
fragment = QuizFragmentSub.newInstance(quiz = quiz),
title = (j + 1).toString()
)
}
// notify the viewpager, I'm using kotlin extension to call widget id
vp_quiz_content.adapter?.notifyDataSetChanged()
// then, childCount will have size > 0
// disable tablayout click
val tabStrip = tabla_quiz_navigation.getChildAt(0) as LinearLayout
for (i in 0 until tabStrip.childCount) {
tabStrip.getChildAt(i).setOnTouchListener { _, _ -> true }
}
}
})
====
// quiz_fragment.xml
<android.support.design.widget.TabLayout
android:id="@+id/tabla_quiz_navigation"
android:layout_width="match_parent"
android:layout_height="wrap_content"></android.support.design.widget.TabLayout>
the method has slightly different on the time of its invocation, you just have to setup your tabitem to disable its click after all viewpager fragment already added.
if there's someone have better approach to this, please edit my answer
Upvotes: 1
Reputation: 2339
You are accessing tabs before setupWithViewPager, thats why your code is not working. So first set tabs then settouchlistener code.
Try this:
tabLayout.setupWithViewPager(viewPager);
setupTabIcons();
LinearLayout tabStrip = ((LinearLayout)mTabLayout.getChildAt(0));
for(int i = 0; i < tabStrip.getChildCount(); i++) {
tabStrip.getChildAt(i).setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
return true;
}
});
}
Upvotes: 55