知乎专栏 |
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.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"> <androidx.cardview.widget.CardView android:layout_width="wrap_content" android:layout_height="wrap_content" app:cardCornerRadius="10dp" app:cardElevation="0dp" tools:ignore="MissingConstraints"> <ImageView android:id="@+id/imageView7" android:layout_width="wrap_content" android:layout_height="wrap_content" android:scaleType="fitXY" app:srcCompat="@drawable/bg_repast_menu" /> </androidx.cardview.widget.CardView> </androidx.constraintlayout.widget.ConstraintLayout>
linearLayoutManager = new LinearLayoutManager(ContextHolder.getContext()); linearLayoutManager.setStackFromEnd(true); recyclerView.setLayoutManager(linearLayoutManager); recyclerView.scrollToPosition(adapter.getItemCount() - 1);
调用下面函数
recyclerView.smoothScrollToPosition(adapter.getItemCount() - 1);
其他用法
// linearLayoutManager.scrollToPositionWithOffset(adapter.getItemCount() - 1, Integer.MIN_VALUE); // linearLayoutManager.scrollToPosition(adapter.getItemCount() - 1);
@NonNull @Override public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { // View view = View.inflate(MainApplication.getContext(), R.layout.recycler_view_chat, null); 这种方式,Item 不会100%充满屏幕 View view = LayoutInflater.from(MainApplication.getContext()).inflate(R.layout.recycler_view_chat, parent, false); ViewHolder viewHolder = new ViewHolder(view); return viewHolder; }
判断是否滑动到顶部/底部:
@Override public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) { if(newState == RecyclerView.SCROLL_STATE_IDLE){//停止滑动 if(recyclerView.canScrollVertically(1)){ Log.d(TAG, "滑动到顶部"); } if(recyclerView.canScrollVertically(-1)){ Log.d(TAG, "滑动到底部"); } } super.onScrollStateChanged(recyclerView, newState); } recyclerView.canScrollVertically(1); false表示不能往上滑动,即代表到顶部了; recyclerView.canScrollVertically(-1); false表示不能往下滑动,即代表到底部了;
判断滑动方向
@Override public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) { if (dy > 0) {//下滑动作 } if (dy < 0) {//上滑动作 } super.onScrolled(recyclerView, dx, dy); }
保存滚动条位置
// Save state Parcelable recyclerViewState = recyclerView.getLayoutManager().onSaveInstanceState(); // Todo // Restore state recyclerView.getLayoutManager().onRestoreInstanceState(recyclerViewState);
View view = binding.recyclerView.getChildAt(0); TextView textView = view.findViewById(R.id.textViewQuestion); textView.setText("Hello");
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL, false); binding.recyclerView.setLayoutManager(linearLayoutManager);
RecyclerView.LayoutManager layoutManager = binding.loraRecyclerView.getLayoutManager(); int childCount = layoutManager.getChildCount(); for (int i = 0; i < childCount; i++) { View childView = layoutManager.getChildAt(i); TextView nameTextView = childView.findViewById(R.id.nameTextView); nameTextView.setBackgroundColor(Color.WHITE); nameTextView.setTextColor(Color.BLACK); }
<com.google.android.material.navigation.NavigationView android:id="@+id/navigationView" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_gravity="start" app:headerLayout="@layout/navigation_header" app:menu="@menu/navigation" />
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android"> <!-- <group android:checkableBehavior="single">--> <!-- <item--> <!-- android:id="@+id/fragment_05"--> <!-- android:title="界面1" />--> <!-- <item--> <!-- android:id="@+id/fragment_06"--> <!-- android:title="界面2" />--> <!-- <item--> <!-- android:id="@+id/fragment_07"--> <!-- android:title="界面3" />--> <!-- </group>--> <group android:id="@+id/groupAi"> <item android:id="@+id/fragment_share" android:icon="@drawable/menu_community" android:title="@string/discovery" /> <item android:id="@+id/menu_story" android:icon="@drawable/menu_story" android:title="@string/story" /> <item android:id="@+id/menu_chat" android:icon="@drawable/menu_chat" android:title="@string/chat" /> </group> <group android:id="@+id/debug" android:visible="false"> <item android:id="@+id/fragment_09" android:icon="@drawable/menu_like" android:title="点赞作品" /> <item android:id="@+id/menu_home" android:icon="@drawable/menu_favorites" android:title="收藏作品"/> <!-- </group>--> <!-- <group android:id="@+id/group_two" >--> <item android:id="@+id/menu_pictur_book" android:icon="@drawable/menu_book" android:title="@string/pictur_book" /> </group> <group android:id="@+id/groupSetting"> <item android:id="@+id/fragment_bind" android:icon="@drawable/menu_bind" android:title="@string/device" /> <item android:id="@+id/fragment_notification" android:icon="@android:drawable/ic_popup_reminder" android:title="消息通知" /> <item android:id="@+id/menu_about" android:icon="?android:attr/actionModeFindDrawable" android:title="@string/about" /> <item android:id="@+id/menu_quit" android:icon="@drawable/menu_quit" android:title="退出" /> </group> </menu>
只显示图标,不显示文字 app:labelVisibilityMode="unlabeled"
<com.google.android.material.bottomnavigation.BottomNavigationView android:id="@+id/nav_view" android:layout_width="match_parent" android:layout_height="40dp" android:background="@android:color/system_neutral2_50" app:itemIconTint="@drawable/navigation_view" app:labelVisibilityMode="unlabeled" app:menu="@menu/bottom_nav_menu" tools:ignore="NewApi" />
.setLabelVisibilityMode(LabelVisibilityMode.LABEL_VISIBILITY_LABELED);
图标不显示原始颜色
setItemIconTintList(null)
文字上下移动,app:itemPaddingBottom="15dp",app:itemPaddingTop="0dp"
<com.google.android.material.bottomnavigation.BottomNavigationView android:id="@+id/nav_view" android:layout_width="match_parent" android:layout_height="40dp" android:background="@android:color/system_neutral2_50" android:gravity="center" app:itemPaddingBottom="15dp" app:itemTextColor="@color/black" app:labelVisibilityMode="labeled" app:menu="@menu/bottom_nav_menu" tools:ignore="NewApi" />
<com.google.android.material.tabs.TabLayout android:id="@+id/tabLayout" android:layout_width="match_parent" android:layout_height="wrap_content"> <com.google.android.material.tabs.TabItem android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="消息" /> <com.google.android.material.tabs.TabItem android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="审核" /> </com.google.android.material.tabs.TabLayout> <androidx.fragment.app.FragmentContainerView android:id="@+id/fragmentContainerViewTabItem" android:name="cn.netkiller.student.ui.message.NotificationFullscreenFragment" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1" android:fitsSystemWindows="true" />
binding.tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() { // 页面被选中 @Override public void onTabSelected(TabLayout.Tab tab) { Log.d(TAG, "onTabSelected: " + tab.getText()); Fragment fragment = null; switch (tab.getPosition()) { // 这里我随便写了两个Fragment case 0: fragment = new NotificationFullscreenFragment(); break; case 1: fragment = new AuditFragment(); break; } if (fragment != null) { getActivity().getSupportFragmentManager().beginTransaction().replace(R.id.fragmentContainerViewTabItem, fragment).commit(); } } // 页面切换到其他 @Override public void onTabUnselected(TabLayout.Tab tab) { Log.d(TAG, "onTabUnselected: " + tab.getText()); } @Override public void onTabReselected(TabLayout.Tab tab) { Log.d(TAG, "onTabReselected: " + tab.getText()); } });
binding.tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() { private boolean isOnTabSelectedListener = false; @Override public void onTabSelected(TabLayout.Tab tab) { if (isOnTabSelectedListener) { Log.e(TAG, "onTabSelected: 暴击 " + tab.getText()); return; } else { new Handler(Looper.getMainLooper()).postDelayed(new Runnable() { public void run() { isOnTabSelectedListener = false; Log.e(TAG, "Tab 释放"); } }, 5000); isOnTabSelectedListener = true; } Log.d(TAG, "onTabSelected: " + tab.getText()); Fragment fragment = null; switch (tab.getPosition()) { case 0: fragment = new NoticeFragment(); break; case 1: fragment = new MessageFragment(); break; case 2: fragment = new AuditFragment(); break; } if (fragment != null) { try { if (!isAdded()) return; // requireActivity().getSupportFragmentManager().beginTransaction().replace(R.id.fragmentContainerViewTabItem, fragment).commit(); getChildFragmentManager().beginTransaction().replace(R.id.fragmentContainerViewTabItem, fragment).commitAllowingStateLoss(); } catch (Exception e) { Log.d(TAG, "Tab 切换出错" + e.getMessage()); } } } // 页面切换到其他 @Override public void onTabUnselected(TabLayout.Tab tab) { Log.d(TAG, "onTabUnselected: " + tab.getText()); } @Override public void onTabReselected(TabLayout.Tab tab) { Log.d(TAG, "onTabReselected: " + tab.getText()); } });
增加间隔时间,并且恢复最后一次点击位置的操作
private void switchTabLayout(int position) { Fragment fragment = null; switch (position) { case 0: fragment = new NoticeFragment(); break; case 1: fragment = new MessageFragment(); break; case 2: fragment = new AuditFragment(); break; } if (fragment != null) { try { if (!isAdded()) return; // requireActivity().getSupportFragmentManager().beginTransaction().replace(R.id.fragmentContainerViewTabItem, fragment).commit(); getChildFragmentManager().beginTransaction().replace(R.id.fragmentContainerViewTabItem, fragment).commitAllowingStateLoss(); } catch (Exception e) { Log.d(TAG, "Tab 切换出错" + e.getMessage()); } } } binding.tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() { private final long interval = 1000L; private boolean isOnTabSelectedListener = false; private int index = 0; @Override public void onTabSelected(TabLayout.Tab tab) { index = tab.getPosition(); if (isOnTabSelectedListener) { Log.e(TAG, "onTabSelected: 暴击 " + tab.getText() + " 位置: " + index); return; } else { new Handler(Looper.getMainLooper()).postDelayed(new Runnable() { public void run() { isOnTabSelectedListener = false; switchTabLayout(index); Log.e(TAG, "Tab 释放,并且切换最后一次点击位置: " + index + " - " + tab.getPosition()); } }, interval); isOnTabSelectedListener = true; } Log.d(TAG, "onTabSelected: " + tab.getText()); switchTabLayout(tab.getPosition()); } // 页面切换到其他 @Override public void onTabUnselected(TabLayout.Tab tab) { Log.d(TAG, "onTabUnselected: " + tab.getText()); } @Override public void onTabReselected(TabLayout.Tab tab) { Log.d(TAG, "onTabReselected: " + tab.getText()); } });
<androidx.viewpager2.widget.ViewPager2 android:id="@+id/viewPager2" android:layout_width="match_parent" android:layout_height="match_parent" />
view_page_layout.xml 文件
<?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"> <TextView android:id="@+id/textView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:text="TextView" /> </LinearLayout>
private List<String> items = List.of("A", "B", "C"); @Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); binding.viewPager2.setAdapter(new ViewPagerAdapter()); }
public class ViewPagerAdapter extends RecyclerView.Adapter<ViewPagerAdapter.CardViewHolder> { @NonNull @Override public ViewPagerAdapter.CardViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { return new CardViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.view_page_layout, parent, false)); } @Override public void onBindViewHolder(@NonNull ViewPagerAdapter.CardViewHolder holder, int position) { holder.textView.setText(items.get(position)); } @Override public int getItemCount() { return items.size(); } public class CardViewHolder extends RecyclerView.ViewHolder { public TextView textView; public CardViewHolder(@NonNull View itemView) { super(itemView); textView = itemView.findViewById(R.id.textView); } } }
<com.google.android.material.tabs.TabLayout android:id="@+id/tabLayout" android:layout_width="match_parent" android:layout_height="wrap_content"> <com.google.android.material.tabs.TabItem android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="推荐" /> </com.google.android.material.tabs.TabLayout> <androidx.viewpager2.widget.ViewPager2 android:id="@+id/viewPager2" android:layout_width="match_parent" android:layout_height="match_parent" />
package cn.netkiller.student.fragment.library; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; import androidx.viewpager2.adapter.FragmentStateAdapter; import com.google.gson.Gson; import java.util.List; import cn.netkiller.student.cloud.PictureBook; import cn.netkiller.student.databinding.FragmentLibraryFullscreenBinding; public class LibraryFullscreenFragment extends Fragment { private static final String TAG = LibraryFullscreenFragment.class.getSimpleName(); private final Gson gson = new Gson(); private FragmentLibraryFullscreenBinding binding; private List<PictureBook.DataResponse.Data> categories; @Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { binding = FragmentLibraryFullscreenBinding.inflate(inflater, container, false); return binding.getRoot(); } @Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); PictureBook pictureBook = new PictureBook(); pictureBook.category(datas -> { categories = datas; requireActivity().runOnUiThread(() -> { categories.forEach(item -> { var tab = binding.tabLayout.newTab(); tab.setText(item.name); binding.tabLayout.addTab(tab); }); binding.viewPager2.setAdapter(new ViewPagerFragmentStateAdapter(this)); }); }); } public class ViewPagerFragmentStateAdapter extends FragmentStateAdapter { public ViewPagerFragmentStateAdapter(@NonNull Fragment fragment) { super(fragment); } @NonNull @Override public Fragment createFragment(int position) { int id = categories.get(position).id; return BookshelfFragment.newInstance(id); } @Override public int getItemCount() { return categories.size(); } } @Override public void onResume() { super.onResume(); } @Override public void onPause() { super.onPause(); } @Override public void onDestroy() { super.onDestroy(); } @Override public void onDestroyView() { super.onDestroyView(); binding = null; } }
package cn.netkiller.student.fragment.library; import android.os.Bundle; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; import cn.netkiller.student.databinding.FragmentBookshelfBinding; public class BookshelfFragment extends Fragment { private static final String TAG = BookshelfFragment.class.getSimpleName(); private FragmentBookshelfBinding binding; private int categoryId; public static BookshelfFragment newInstance(int categoryId) { BookshelfFragment fragment = new BookshelfFragment(); Bundle args = new Bundle(); args.putInt("categoryId", categoryId); // args.putString(ARG_PARAM2, param2); fragment.setArguments(args); return fragment; } @Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { binding = FragmentBookshelfBinding.inflate(inflater, container, false); if (getArguments() != null) { categoryId = getArguments().getInt("categoryId"); } return binding.getRoot(); } @Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); Log.d(TAG, "Categroy Id: " + categoryId); binding.fullscreenContent.setText(categoryId + ""); } @Override public void onResume() { super.onResume(); } @Override public void onPause() { super.onPause(); } @Override public void onDestroy() { super.onDestroy(); } @Override public void onDestroyView() { super.onDestroyView(); binding = null; } }
@Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); PictureBook pictureBook = new PictureBook(); pictureBook.category(datas -> { categories = datas; requireActivity().runOnUiThread(() -> { categories.forEach(item -> { var tab = binding.tabLayout.newTab(); tab.setText(item.name); binding.tabLayout.addTab(tab); }); binding.viewPager2.setAdapter(new ViewPagerFragmentStateAdapter(this)); new TabLayoutMediator(binding.tabLayout, binding.viewPager2, new TabLayoutMediator.TabConfigurationStrategy() { @Override public void onConfigureTab(@NonNull TabLayout.Tab tab, int position) { tab.setText(categories.get(position).name); } }).attach(); }); }); }