RecyclerView和CardView的使用以及注意

转载请注明出处
作者:AboutJoke ( http://blog.csdn.net/u013200308 )
原文链接:http://blog.csdn.net/u013200308/article/details/51244289

距离RecyclerView和CardView的出现已经很久了,网上也有很多关于这方面的博客。因为最近自己在项目中用到了Material Design设计规范,所以才第一次接触到了RecyclerView和CardView。在这篇博客中,我将给大家介绍一下RecyclerView和CardView的使用方法以及在使用过程中可能遇到的一些问题。具体的实现将通过一个Demo来进行介绍。

RecyclerView和CardView的简单介绍

2014年,随着Google推出了全新的设计语言Material Design,还迎来了新的Android支持库v7,其中就包含了RecyclerView和CardView。可在路径sdk\extras\android\support\v7下找到相关的support包,通过导入来进行依赖。


RecyclerView

我们为什么要去使用RecyclerView呢?对比我们最常用的ListView,可以发现以下几点:

1.使用方法
ListView仅需要设置adapter即可正常使用,而RecyclerView需要

//设置布局管理器
list.setLayoutManager(new LinearLayoutManager(this));
//设置adapter
list.setAdapter(adapter)
//设置Item增加、移除动画
list.setItemAnimator(new DefaultItemAnimator());

2.ViewHolder
在我们使用ListViewz中,我们经常会使用ViewHolder来进行复用,而在RecyclerView中则直接提供了ViewHolder,我们可以通过继承来使用。

通过以上我们可以发现,RecyclerView正如其命名,只负责对view的回收和复用,其他的一切都交给程序员来实现。这样我们才可以轻松的通过RecyclerView这个控件来实现ListView,GirdView,瀑布流等效果。


CardView

通过CardView我们可以很容易的实现卡片式的布局,当然你也可以使用Drawable、Layout 来实现。但这毕竟需要一定的功底,所以对于不擅长的同学来说,CardVi

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面是完整的代码实现: 1. 添加HanziToPinyin类 ``` public class HanziToPinyin { private HanyuPinyinOutputFormat format = null; public HanziToPinyin() { format = new HanyuPinyinOutputFormat(); format.setCaseType(HanyuPinyinCaseType.UPPERCASE); format.setToneType(HanyuPinyinToneType.WITHOUT_TONE); format.setVCharType(HanyuPinyinVCharType.WITH_V); } public String getPinyin(String src) { char[] srcChar = src.toCharArray(); String[] srcStr = new String[srcChar.length]; for (int i = 0; i < srcChar.length; i++) { srcStr[i] = Character.toString(srcChar[i]); } String[] pinYin = new String[srcStr.length]; for (int i = 0; i < srcStr.length; i++) { // 判断是否为汉字字符 if (srcStr[i].matches("[\\u4e00-\\u9fa5]+")) { try { pinYin[i] = PinyinHelper.toHanyuPinyinStringArray(srcChar[i], format)[0]; } catch (BadHanyuPinyinOutputFormatCombination e) { e.printStackTrace(); } } else { pinYin[i] = srcStr[i]; } } StringBuilder builder = new StringBuilder(); for (String s : pinYin) { builder.append(s); } return builder.toString(); } } ``` 2. 创建RecyclerView的布局文件`activity_main.xml`和`item_application.xml`。 `activity_main.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" android:orientation="horizontal"> <androidx.recyclerview.widget.RecyclerView android:id="@+id/recyclerView" android:layout_width="match_parent" android:layout_height="match_parent" /> <TextView android:id="@+id/letter" android:layout_width="50dp" android:layout_height="50dp" android:gravity="center" android:textSize="20sp" android:textColor="#000000" android:background="@drawable/background_letter" android:visibility="gone" /> </LinearLayout> ``` `item_application.xml`的代码如下: ``` <?xml version="1.0" encoding="utf-8"?> <androidx.cardview.widget.CardView 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="wrap_content" android:layout_marginTop="10dp" app:cardCornerRadius="8dp" app:cardElevation="4dp"> <TextView android:id="@+id/applicationName" android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="16dp" android:textSize="16sp" android:textColor="#000000" /> </androidx.cardview.widget.CardView> ``` 3. 创建`ApplicationViewHolder`类 ``` public class ApplicationViewHolder extends RecyclerView.ViewHolder { private TextView applicationName; public ApplicationViewHolder(@NonNull View itemView) { super(itemView); applicationName = itemView.findViewById(R.id.applicationName); } public void bind(String packageName) { PackageManager pm = itemView.getContext().getPackageManager(); String name = null; try { name = pm.getApplicationLabel(pm.getApplicationInfo(packageName, PackageManager.GET_META_DATA)).toString(); } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); } applicationName.setText(name); } } ``` 4. 创建`MainActivity`类 ``` public class MainActivity extends AppCompatActivity { private RecyclerView recyclerView; private TextView letter; private ApplicationAdapter adapter; private List<String> packageNames = new ArrayList<>(); private List<String> sortedPackageNames = new ArrayList<>(); private Map<String, Integer> letterPosition = new HashMap<>(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); recyclerView = findViewById(R.id.recyclerView); letter = findViewById(R.id.letter); recyclerView.setLayoutManager(new LinearLayoutManager(this)); recyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL)); adapter = new ApplicationAdapter(sortedPackageNames); recyclerView.setAdapter(adapter); getPackageNames(); sortPackageNames(); initLetterPosition(); recyclerView.addOnItemTouchListener(new RecyclerView.OnItemTouchListener() { @Override public boolean onInterceptTouchEvent(@NonNull RecyclerView rv, @NonNull MotionEvent e) { if (e.getAction() == MotionEvent.ACTION_DOWN) { int position = recyclerView.getChildAdapterPosition(rv.findChildViewUnder(e.getX(), e.getY())); if (position != RecyclerView.NO_POSITION) { String letter = getFirstLetter(sortedPackageNames.get(position)); showLetter(letter); int newPosition = letterPosition.get(letter); recyclerView.smoothScrollToPosition(newPosition); return true; } } return false; } @Override public void onTouchEvent(@NonNull RecyclerView rv, @NonNull MotionEvent e) { } @Override public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) { } }); recyclerView.setOnScrollChangeListener((v, scrollX, scrollY, oldScrollX, oldScrollY) -> { View view = recyclerView.findChildViewUnder(letter.getWidth() / 2, letter.getHeight() / 2); if (view != null) { int position = recyclerView.getChildAdapterPosition(view); String letter = getFirstLetter(sortedPackageNames.get(position)); showLetter(letter); } }); } private void getPackageNames() { PackageManager pm = getPackageManager(); List<ApplicationInfo> apps = pm.getInstalledApplications(0); for (ApplicationInfo app : apps) { packageNames.add(app.packageName); } } private void sortPackageNames() { HanziToPinyin hanziToPinyin = new HanziToPinyin(); List<String> pinyinPackageNames = new ArrayList<>(); for (String packageName : packageNames) { String name = null; try { name = getPackageManager().getApplicationLabel(getPackageManager().getApplicationInfo(packageName, PackageManager.GET_META_DATA)).toString(); } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); } String pinyin = hanziToPinyin.getPinyin(name); pinyinPackageNames.add(pinyin + "#" + packageName); } Collections.sort(pinyinPackageNames); for (String pinyinPackageName : pinyinPackageNames) { String packageName = pinyinPackageName.substring(pinyinPackageName.indexOf("#") + 1); sortedPackageNames.add(packageName); } } private void initLetterPosition() { String lastLetter = null; for (int i = 0; i < sortedPackageNames.size(); i++) { String letter = getFirstLetter(sortedPackageNames.get(i)); if (!letter.equals(lastLetter)) { letterPosition.put(letter, i); lastLetter = letter; } } } private String getFirstLetter(String s) { String pinyin = HanziToPinyin.getInstance().getPinyin(s); String firstLetter = pinyin.substring(0, 1); if (!firstLetter.matches("[A-Za-z]")) { firstLetter = "#"; } return firstLetter.toUpperCase(); } private void showLetter(String letter) { this.letter.setText(letter); this.letter.setVisibility(View.VISIBLE); new Handler().postDelayed(() -> this.letter.setVisibility(View.GONE), 1000); } private class ApplicationAdapter extends RecyclerView.Adapter<ApplicationViewHolder> { private List<String> packageNames; public ApplicationAdapter(List<String> packageNames) { this.packageNames = packageNames; } @NonNull @Override public ApplicationViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_application, parent, false); return new ApplicationViewHolder(view); } @Override public void onBindViewHolder(@NonNull ApplicationViewHolder holder, int position) { String packageName = packageNames.get(position); holder.bind(packageName); } @Override public int getItemCount() { return packageNames.size(); } } } ``` 在`MainActivity`中,我们首先获取所有应用程序的包名和应用程序名称,并将其存储在一个列表中。然后,我们按照首字母对包名进行排序,并初始化字母与位置的映射表。接下来,我们创建一个自定义RecyclerView.Adapter,在其中实现适当的方法。最后,我们实现了字幕条索引,并在RecyclerView上添加了一个FastScroller,使用`setOnTouchLetterChangeListenner`方法来监听字母条的触摸事件。 注意事项: 1. 代码中使用androidx库。 2. 需要在`AndroidManifest.xml`文件中添加`<uses-permission android:name="android.permission.GET_TASKS" />`权限。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值