• Android学习笔记 83. 卡片和颜色


    Android学习笔记

    Android 开发者基础知识 (Java) —— Google Developers 培训团队

    第2单元 用户体验

    第5课 愉悦的用户体验

    83. 卡片和颜色
    你会做什么
    • 修改应用程序以遵循 Material Design准则。
    • 将图像和样式添加到 RecyclerView列表中。
    • 实现一个 ItemTouchHelper以将拖放功能添加到您的应用程序。
    83.1 下载入门代码

    项目地址:https://github.com/google-developer-training/android-fundamentals-starter-apps/tree/master/MaterialMe-Starter

    1. 打开并运行MaterialMe项目

      在这里插入图片描述

      直接构建错误了…

      有些年代了这项目,

      复刻一个

      创建新项目

      在这里插入图片描述

      主布局activity_main.xml

      
      <RelativeLayout 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"
          android:paddingLeft="@dimen/activity_horizontal_margin"
          android:paddingTop="@dimen/activity_vertical_margin"
          android:paddingRight="@dimen/activity_horizontal_margin"
          android:paddingBottom="@dimen/activity_vertical_margin"
          tools:context=".MainActivity">
      
      
          <androidx.recyclerview.widget.RecyclerView
              android:id="@+id/recyclerview"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:scrollbars="vertical" />
      
      
          <com.google.android.material.floatingactionbutton.FloatingActionButton
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:layout_alignParentEnd="true"
              android:layout_alignParentRight="true"
              android:layout_alignParentBottom="true"
              android:layout_margin="16dp"
              android:onClick="resetSports"
              android:src="@drawable/ic_reset"
              android:tint="@android:color/white" />
      
      
      RelativeLayout>
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32

      list_item.xml

      
      
      <androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
          android:layout_width="match_parent"
          android:layout_height="wrap_content"
          android:layout_margin="8dp">
      
          <RelativeLayout
              android:layout_width="match_parent"
              android:layout_height="wrap_content">
      
              <ImageView
                  android:id="@+id/sportsImage"
                  android:layout_width="match_parent"
                  android:layout_height="wrap_content"
                  android:adjustViewBounds="true" />
      
              <TextView
                  android:id="@+id/title"
                  style="@style/TextAppearance.AppCompat.Headline"
                  android:layout_width="wrap_content"
                  android:layout_height="wrap_content"
                  android:layout_alignBottom="@id/sportsImage"
                  android:padding="8dp"
                  android:text="@string/title_placeholder"
                  android:theme="@style/ThemeOverlay.AppCompat.Dark" />
      
              <TextView
                  android:id="@+id/newsTitle"
                  style="@style/TextAppearance.AppCompat.Subhead"
                  android:layout_width="wrap_content"
                  android:layout_height="wrap_content"
                  android:layout_below="@id/sportsImage"
                  android:padding="8dp"
                  android:text="@string/news_placeholder"
                  android:textColor="?android:textColorSecondary" />
              
              <TextView
                  android:id="@+id/subTitle"
                  style="@style/TextAppearance.AppCompat.Subhead"
                  android:layout_width="wrap_content"
                  android:layout_height="wrap_content"
                  android:layout_below="@id/newsTitle"
                  android:text="@string/sports_info_placeholder" />
              
          RelativeLayout>
      androidx.cardview.widget.CardView>
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38
      • 39
      • 40
      • 41
      • 42
      • 43
      • 44
      • 45
      • 46
      • 47

      新建一个Activity,DetailActivity.java

      在这里插入图片描述

      package com.dingjiaxiong.materialme;
      
      import androidx.appcompat.app.AppCompatActivity;
      
      import android.os.Bundle;
      import android.widget.ImageView;
      import android.widget.TextView;
      
      import com.bumptech.glide.Glide;
      
      public class DetailActivity extends AppCompatActivity {
      
          @Override
          protected void onCreate(Bundle savedInstanceState) {
              super.onCreate(savedInstanceState);
              setContentView(R.layout.activity_detail);
      
      
              TextView sportTitle = findViewById(R.id.titleDetail);
              ImageView sportImage = findViewById(R.id.sportsImageDetail);
      
      
              sportTitle.setText(getIntent().getStringExtra("title"));
      
              Glide.with(this).load(getIntent().getIntExtra("image_resource",0))
                      .into(sportImage);
      
          }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29

      布局文件

      activity_detail.xml

      
      
      <ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
          android:layout_width="match_parent"
          android:layout_height="match_parent">
      
      
          <RelativeLayout xmlns:tools="http://schemas.android.com/tools"
              android:layout_width="match_parent"
              android:layout_height="wrap_content"
              tools:context=".DetailActivity">
      
              <ImageView
                  android:id="@+id/sportsImageDetail"
                  android:layout_width="match_parent"
                  android:layout_height="wrap_content"
                  android:adjustViewBounds="true" />
      
              <TextView
                  android:id="@+id/titleDetail"
                  style="@style/TextAppearance.AppCompat.Headline"
                  android:layout_width="wrap_content"
                  android:layout_height="wrap_content"
                  android:layout_alignBottom="@id/sportsImageDetail"
                  android:padding="16dp"
                  android:text="@string/title_placeholder"
                  android:theme="@style/ThemeOverlay.AppCompat.Dark" />
      
      
              <TextView
                  android:id="@+id/newsTitleDetail"
                  style="@style/TextAppearance.AppCompat.Subhead"
                  android:layout_width="wrap_content"
                  android:layout_height="wrap_content"
                  android:layout_below="@id/sportsImageDetail"
                  android:padding="16dp"
                  android:text="@string/news_placeholder"
                  android:textColor="?android:textColorSecondary" />
      
              <TextView
                  android:id="@+id/subTitleDetail"
                  style="@style/TextAppearance.AppCompat.Subhead"
                  android:layout_width="wrap_content"
                  android:layout_height="wrap_content"
                  android:layout_below="@id/newsTitleDetail"
                  android:padding="16dp"
                  android:text="@string/subtitle_detail_text" />
      
      
          RelativeLayout>
      
      
      ScrollView>
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38
      • 39
      • 40
      • 41
      • 42
      • 43
      • 44
      • 45
      • 46
      • 47
      • 48
      • 49
      • 50
      • 51
      • 52
      • 53

      新建Sport.java

      package com.dingjiaxiong.materialme;
      
      public class Sport {
      
      
          private String title;
          private String info;
          private final int imageResource;
      
          public Sport(String title, String info, int imageResource) {
              this.title = title;
              this.info = info;
              this.imageResource = imageResource;
          }
      
          public String getTitle() {
              return title;
          }
      
          public String getInfo() {
              return info;
          }
      
          public int getImageResource() {
              return imageResource;
          }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27

      新建适配器SportsAdapter.java

      package com.dingjiaxiong.materialme;
      
      import android.content.Context;
      import android.content.Intent;
      import android.view.LayoutInflater;
      import android.view.View;
      import android.view.ViewGroup;
      import android.widget.ImageView;
      import android.widget.TextView;
      
      import androidx.annotation.NonNull;
      import androidx.recyclerview.widget.RecyclerView;
      
      import com.bumptech.glide.Glide;
      
      import java.util.ArrayList;
      
      public class SportsAdapter extends RecyclerView.Adapter<SportsAdapter.ViewHolder> {
      
      
          private ArrayList<Sport> mSportData;
          private Context mContext;
      
      
          public SportsAdapter(ArrayList<Sport> mSportData, Context mContext) {
              this.mSportData = mSportData;
              this.mContext = mContext;
          }
      
          @NonNull
          @Override
          public SportsAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
              return new ViewHolder(LayoutInflater.from(mContext).inflate(R.layout.list_item, parent, false));
          }
      
          @Override
          public void onBindViewHolder(@NonNull SportsAdapter.ViewHolder holder, int position) {
              Sport currentSport = mSportData.get(position);
              holder.bindTo(currentSport);
          }
      
          @Override
          public int getItemCount() {
              return mSportData.size();
          }
      
      
          class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
      
              private TextView mTitleText;
              private TextView mInfoText;
              private ImageView mSportImage;
      
              public ViewHolder(@NonNull View itemView) {
                  super(itemView);
      
                  mTitleText = itemView.findViewById(R.id.title);
                  mInfoText = itemView.findViewById(R.id.subTitle);
                  mSportImage = itemView.findViewById(R.id.sportsImage);
      
                  itemView.setOnClickListener(this);
              }
      
              @Override
              public void onClick(View v) {
                  Sport currentSport = mSportData.get(getAdapterPosition());
                  Intent detailIntent = new Intent(mContext, DetailActivity.class);
                  detailIntent.putExtra("title", currentSport.getTitle());
                  detailIntent.putExtra("image_resource", currentSport.getImageResource());
      
                  mContext.startActivity(detailIntent);
              }
      
              public void bindTo(Sport currentSport) {
                  mTitleText.setText(currentSport.getTitle());
                  mInfoText.setText(currentSport.getInfo());
      
                  Glide.with(mContext).load(currentSport.getImageResource()).into(mSportImage);
              }
          }
      
      }
      
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38
      • 39
      • 40
      • 41
      • 42
      • 43
      • 44
      • 45
      • 46
      • 47
      • 48
      • 49
      • 50
      • 51
      • 52
      • 53
      • 54
      • 55
      • 56
      • 57
      • 58
      • 59
      • 60
      • 61
      • 62
      • 63
      • 64
      • 65
      • 66
      • 67
      • 68
      • 69
      • 70
      • 71
      • 72
      • 73
      • 74
      • 75
      • 76
      • 77
      • 78
      • 79
      • 80
      • 81
      • 82
      • 83

      这里用到了Glide,需要手动导入

      implementation 'com.github.bumptech.glide:glide:4.13.2'
      annotationProcessor 'com.github.bumptech.glide:compiler:4.13.2'
      
      • 1
      • 2

      最后MainActivity.java

      package com.dingjiaxiong.materialme;
      
      import androidx.annotation.NonNull;
      import androidx.appcompat.app.AppCompatActivity;
      import androidx.recyclerview.widget.ItemTouchHelper;
      import androidx.recyclerview.widget.LinearLayoutManager;
      import androidx.recyclerview.widget.RecyclerView;
      
      import android.content.res.TypedArray;
      import android.os.Bundle;
      import android.view.View;
      
      import java.util.ArrayList;
      import java.util.Collections;
      
      public class MainActivity extends AppCompatActivity {
      
          private RecyclerView mRecyclerView;
          private ArrayList<Sport> mSportsData;
          private SportsAdapter mAdapter;
      
      
          @Override
          protected void onCreate(Bundle savedInstanceState) {
              super.onCreate(savedInstanceState);
              setContentView(R.layout.activity_main);
      
      
              mRecyclerView = findViewById(R.id.recyclerview);
              mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
      
              mSportsData = new ArrayList<>();
      
              mAdapter = new SportsAdapter(mSportsData, this);
      
              mRecyclerView.setAdapter(mAdapter);
      
              //获取数据
              initializeData();
      
              ItemTouchHelper helper = new ItemTouchHelper(new ItemTouchHelper.SimpleCallback(
                      ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT |
                              ItemTouchHelper.DOWN | ItemTouchHelper.UP,
                      ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT
              ) {
                  @Override
                  public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder target) {
                      int from = viewHolder.getAdapterPosition();
                      int to = target.getAdapterPosition();
      
                      Collections.swap(mSportsData, from, to);
                      mAdapter.notifyItemMoved(from, to);
                      return true;
                  }
      
                  @Override
                  public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) {
                      mSportsData.remove(viewHolder.getAdapterPosition());
      
                      mAdapter.notifyItemRemoved(viewHolder.getAdapterPosition());
                  }
              });
      
              helper.attachToRecyclerView(mRecyclerView);
      
          }
      
          private void initializeData() {
              String[] sportsList = getResources()
                      .getStringArray(R.array.sports_titles);
      
              String[] sportsInfo = getResources()
                      .getStringArray(R.array.sports_info);
      
              TypedArray sportsImageResources = getResources()
                      .obtainTypedArray(R.array.sports_images);
      
              mSportsData.clear();
      
              for (int i = 0; i < sportsList.length ; i++){
                  mSportsData.add(new Sport(sportsList[i],sportsInfo[i],sportsImageResources.getResourceId(i,0)));
              }
      
              sportsImageResources.recycle();
      
              mAdapter.notifyDataSetChanged();
      
          }
      
      
          public void resetSports(View view) {
              initializeData();
          }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38
      • 39
      • 40
      • 41
      • 42
      • 43
      • 44
      • 45
      • 46
      • 47
      • 48
      • 49
      • 50
      • 51
      • 52
      • 53
      • 54
      • 55
      • 56
      • 57
      • 58
      • 59
      • 60
      • 61
      • 62
      • 63
      • 64
      • 65
      • 66
      • 67
      • 68
      • 69
      • 70
      • 71
      • 72
      • 73
      • 74
      • 75
      • 76
      • 77
      • 78
      • 79
      • 80
      • 81
      • 82
      • 83
      • 84
      • 85
      • 86
      • 87
      • 88
      • 89
      • 90
      • 91
      • 92
      • 93
      • 94
    2. 运行一把

      官方效果图

      在这里插入图片描述

      在这里插入图片描述

      复刻成功

    3. 探索应用程序

      Sport.java
      
      • 1

      此类表示RecyclerView. 现在,它包含一个用于运动标题的字段和一个用于该运动的一些信息的字段。

      SportsAdapter.java
      
      • 1

      这是RecyclerView. 它使用一个ArrayListSport 对象作为其数据,并用该数据填充每一行。

      MainActivity.java
      
      • 1

      MainActivity初始化 RecyclerView 和适配器,并从资源文件创建数据。

      strings.xml
      
      • 1

      此资源文件包含应用程序的所有数据,包括每项运动的标题和信息。

      list_item.xml
      
      • 1

      此布局文件定义RecyclerView. 它由三个TextView元素组成,一个用于每条数据(每项运动的标题和信息),另一个用作标签。

    其实到这里,笔者复刻出来后,本此课要讲的东西就结束了,走下流程吧。

    83.2 添加CardView和图像

    又是新知识

    【卡片视图】不错

    1. 添加卡片视图
    2. 下载图片
    3. 修改Sport对象
    4. 修改初始化的方法initializeData()
    5. 将ImageView添加到列表项
    6. 使用Glide加载图像
    83.3 使CardView可滑动、可移动和可点击
    1. 实现滑动关闭

      Android SDK 包含一个名为的类 ItemTouchHelper,用于定义RecyclerView当用户执行各种触摸操作(例如滑动或拖放)时列表项会发生什么。

    2. 实现拖放

    3. 实现DetailActivity详情页布局

    4. 实现详情视图和点击事件的监听

    83.4 添加FAB并选择Material Design调色板
    1. 添加FAB
    2. 选择Material设计调色板
    83.5 小结
    • CardView是一个很好的布局,用于呈现具有混合媒体(例如图像和文本)的信息。
    • CardView是 Android 支持库中的一个 UI 组件。
    • CardView不仅仅是为文本子View元素设计的。
    • 将图像直接加载到ImageView内存中会占用大量内存,因为图像是以全分辨率加载的。为了有效地将图像加载到您的应用程序中,请使用图像加载库,例如 Glide。
    • Android SDK 有一个名为的类 ItemTouchHelper,可帮助您的应用获取有关 UI 中的点击、滑动和拖放事件的信息。
    • A FloatingActionButton(FAB) 让用户关注特定操作并在您的 UI 中“浮动”。
    • Material Design 是一组用于创建一致、直观和有趣的应用程序的指导原则。
    • 根据 Material Design,为您的应用选择三种颜色是一种很好的做法:原色、深色原色和强调色。
    • Material Design 提倡使用大胆的图像和颜色来增强用户体验。它还促进跨平台的一致元素,例如通过使用CardView和 FAB 小部件。
    • 使用 Material Design 为 UI 元素创建有意义的、直观的运动,例如可以关闭或重新排列的卡片。
  • 相关阅读:
    Mysql 都有那些最需要掌握的原理?
    【Mybatis编程:修改数据(动态SQL)】
    Spring 常用注解及作用
    GBase 8c查看数据
    __attribute__((visibility(“default“)))含义
    第17章_其他数据库日志
    虹科干货 | 虹科带你了解车载以太网-SOME/IP协议
    骑行探秘,海晏村贝丘渔场之旅,一场与大自然的亲密邂逅
    计算机网络-传输层(传输层概述,TCP,UDP协议概述)
    热重分析(TGA)真空试验中的真空度精密控制解决方案
  • 原文地址:https://blog.csdn.net/weixin_44226181/article/details/126399309