Android
目前安卓开发有两种语言可以选择,java或者Kotlin,Kotlin比起Java来说更加简洁,且优化了不少写法
安卓开发的框架呢有Jetpack Compose,使用声明式开发,基本语法方面与SwiftUI大相径庭,但是只适用于Kotlin语言
使用xml去布局activity(页面),使用java去编写逻辑(相当于javascript)
要编写逻辑时,需要用id(XXXX xxxx=findViewById(R.id.xxxx))去找到该控件,实例化之后再去进行后续操作
简单控件
text
单位有px,dp(常用),sp(字体专用,会根据系统文字大小进行调整,一般情况下与dp大小一致)
一般是在@String里面(values包下面)去写文字,这样方便一次修改,以及后续调整语言
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 95 96 97 98 99
   | <?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:layout_margin="@dimen/dimen_20"     android:orientation="vertical">          <TextView         android:id="@+id/textView"         android:layout_width="match_parent"         android:layout_height="wrap_content"         android:text="TextView" />                         <TextView         android:layout_width="match_parent"         android:layout_height="wrap_content"         android:text="@string/str_setting_color_size"         android:layout_marginTop="@dimen/dimen_10"         android:textColor="@color/color_ff0000"         android:textSize="@dimen/text_size_20" />               
           <TextView         android:layout_width="match_parent"         android:layout_height="wrap_content"         android:drawableLeft="@mipmap/ic_launcher"         android:layout_marginTop="@dimen/dimen_10"         android:gravity="center_vertical"         android:shadowColor="@color/color_FF773D"         android:shadowDx="30"         android:shadowDy="-20"         android:shadowRadius="2"         android:text="右侧添加图片和使用阴影"         android:textColor="@color/color_188FFF"         android:textSize="@dimen/text_size_20" />               <TextView         android:layout_width="match_parent"         android:layout_height="wrap_content"         android:autoLink="email|phone"         android:gravity="center_vertical"         android:layout_marginTop="@dimen/dimen_10"         android:text="可点击跳转邮件:SCC5201314@qq.com\n可点击跳转电话:0215201314"         android:textColor="@color/color_188FFF"         android:textSize="@dimen/text_size_14" />                         <TextView         android:layout_width="match_parent"         android:layout_height="wrap_content"         android:ellipsize="end"         android:gravity="center_vertical"         android:lineSpacingMultiplier="1.2"         android:layout_marginTop="@dimen/dimen_10"         android:maxLength="2"         android:text="TxtView继承了View,它还是Button、EditText两个UI组件类的父类。它的作用是在用户界面上显示文本素。从功能上来看TextView就是个文本编辑器,只不过Android关闭的它的可编辑功能。如果需要一个可编辑的文本框,就要使用到它的子类Editext了,Editext允许用户编辑文本框中的内容。TextView和Editext它俩最大的区别就在于TextView不允许用户编辑文本内容,Editext允许用户编辑文本内容。 下面咱写几个实例来详细了解一下TextView的。"         android:textColor="@color/color_188FFF"         android:textSize="@dimen/text_size_14" />               <TextView         android:layout_width="wrap_content"         android:layout_height="wrap_content"         android:background="@color/color_ff0000"         android:layout_marginTop="@dimen/dimen_10"         android:padding="10dp"         android:text="背景色红色的文本"         android:textColor="@color/white" />                 <TextView         android:layout_width="wrap_content"         android:layout_height="wrap_content"         android:layout_marginTop="@dimen/dimen_10"         android:background="@drawable/bg_tv_frame_red"         android:padding="10dp"         android:text="带着红色边框的文本" />               <TextView         android:layout_width="wrap_content"         android:layout_height="wrap_content"         android:layout_marginTop="@dimen/dimen_10"         android:background="@drawable/bg_tv_frame_gradient"         android:padding="10dp"         android:textColor="@color/white"         android:text="带着边框和背景色渐变的文本" /> </LinearLayout>
   | 
 
LinearLayout
线性布局
使用orientation属性控制排列方式,默认水平排列
水平:orientation:horizontal
垂直:orientation:vertical
使用layout_weight属性控制权重,相当于各自拥有多大比例
Layout_width为0dp时,layout_weight表示水平方向的宽度比例
Layout_height为0dp时,layout_weight表示垂直方向的宽度比例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
   | <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"     xmlns:tools="http://schemas.android.com/tools"     android:layout_width="400dp"     android:layout_height="300dp"     android:background="@color/teal_200"     android:orientation="horizontal"     tools:context=".MainActivity">
      <Button         android:id="@+id/button1"         android:layout_width="100dp"         android:layout_weight="3"         android:layout_height="wrap_content"         android:text="Button" />
      <Button         android:id="@+id/button2"         android:layout_weight="1"         android:layout_width="wrap_content"         android:layout_height="wrap_content"         android:text="Button" />
  </LinearLayout>
   | 
 
RelativeLayout
相对布局,感觉比较像css里的绝对定位
布局方式:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
   | //左上 android:layout_alignParentTop="true" android:layout_alignParentLeft="true"
  //右上 android:layout_alignParentTop="true" android:layout_alignParentRight="true"//不设置基于右侧,会自动设置为基于左侧
  //左下 android:layout_alignParentBottom="true"  //不设置基于底部,会自动设置为基于顶部 android:layout_alignParentLeft="true"   
  //右下 android:layout_alignParentBottom="true"  //不设置基于底部,会自动设置为基于顶部 android:layout_alignParentRight="true"  //不设置基于右侧,会自动设置为基于左侧
  android:layout_above="@id/button3"    //居中控件顶部 android:layout_below="@id/button3"    //居中控件底部 android:layout_toLeftOf="@id/button3"  //居中控件左侧 android:layout_toRightOf="@id/button3"  //居中控件右侧
 
   | 
 
GridLayout
设置几行几列
| 属性 | 
说明 | 
| android:rowCount | 
设置网格布局有几行 | 
| android:columnCount | 
设置网格布局有几列 | 
设置组件所在的行或列
注意: 行列从 0 开始计算,比如第一行是 0 ,第二行是 1
| 属性 | 
说明 | 
| android:layout_row | 
设置组件位于第几行 | 
| android:layout_column | 
设置组件位于第几列 | 
设置组件跨几行几列
| 属性 | 
说明 | 
| android:layout_rowSpan | 
设置组件跨几行 | 
| android:layout_columnSpan | 
设置组件跨几列 | 
ScrollView 是一个竖直滚动条,水平方向上的滚动条为 HorizontalScrollView
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
   | <?xml version="1.0" encoding="utf-8" ?> <LinearLayout 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:padding="8dp"      android:orientation="vertical" >
      <ScrollView        <!--注意ScrollView为竖直滚动,所以layout_width必须match_parent  			 <!--同理HorizontalScrollView为水平滚动,所以layout_height必须match_parent-->         android:id="@+id/scrollview"         android:layout_width="match_parent"          android:layout_height="500dp">
          <TextView             android:layout_width="match_parent"              android:layout_height="wrap_content"             android:text="@string/chuliuxiang" />     </ScrollView> </LinearLayout>
   | 
 
事件
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
   | public class MainActivity extends AppCompatActivity {
      @Override     protected void onCreate(Bundle savedInstanceState) {         super.onCreate(savedInstanceState);         setContentView(R.layout.activity_main);
  				         Button btn1=findViewById(R.id.btn1);                           btn1.setOnClickListener(new View.OnClickListener() {             @Override             public void onClick(View v) {                              }         });
                   btn1.setOnLongClickListener(new View.OnLongClickListener() {             @Override             public boolean onLongClick(View v) {                                  return false;             }         });
                   btn1.setOnTouchListener(new View.OnTouchListener() {             @Override             public boolean onTouch(View v, MotionEvent event) {                                  return false;             }         });
      } }
 
  | 
 
ImageView
1 2 3 4 5 6 7 8 9
   |  <ImageView      android:id="@+id/iv"      android:layout_width="200dp"      android:layout_height="200dp"      android:layout_centerHorizontal="true"      android:scaleType="fitCenter"       android:src="@drawable/developer"      android:background="@drawable/developer" />
 
  | 
 
include
相当于引入组件,优化了代码
1
   | <include layout="@layout/activity_drawer_menu" android:id="@+id/drawerMenu1"/>
   | 
 
DrawerLayout
安卓自带的抽屉式菜单
使用方法为分为两部分,一个是正文部分(必须放在最上面),一个是菜单部分,其中如果是左侧拉出的菜单就必须要加上android:layout_gravity=”start”,同理右侧拉出则改为end,注意下面的代码我进行了封装,而使用后发现只有NavigationView才能加上layout_gravity这个属性
xml部分的使用
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
   | <?xml version="1.0" encoding="utf-8"?> <androidx.drawerlayout.widget.DrawerLayout 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"     android:id="@+id/drawerLayout">     <LinearLayout         android:layout_width="match_parent"         android:layout_height="match_parent"         android:orientation="vertical"         android:padding="15dp">              </LinearLayout>   	     <com.google.android.material.navigation.NavigationView         android:layout_width="210dp"         android:layout_height="match_parent"         android:layout_gravity="start">         <include             android:id="@+id/drawerMenu"             layout="@layout/activity_drawer_menu"/>     </com.google.android.material.navigation.NavigationView> </androidx.drawerlayout.widget.DrawerLayout>
   | 
 
java部分的使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
   | public class MainActivity extends AppCompatActivity {     @Override     protected void onCreate(Bundle savedInstanceState) {         super.onCreate(savedInstanceState);         setContentView(R.layout.activity_main);
                   View Nav = findViewById(R.id.Nav);
          ImageView navMenuImageView = Nav.findViewById(R.id.navMenu);         navMenuImageView.setOnClickListener(new View.OnClickListener() {             @Override             public void onClick(View v) {                                  Log.v("drawerMenu","点击成功");                 DrawerLayout drawerLayout = findViewById(R.id.drawerLayout);                 drawerLayout.openDrawer(GravityCompat.START);              }         });     } }
  | 
 
NavigationView
这个视图相当于一个封装好的菜单,在menu属性部分存入主体菜单的布局,在headerLayout属性部分存入头部菜单的布局(比如头像姓名)
RecyclerView
这个控件是用来展示大量数据,它比ListView的优势在于能够回收利用数据(名字的由来)同时可以选择单列展示,双列展示,瀑布流展示
xml部分:
1 2 3 4
   | <androidx.recyclerview.widget.RecyclerView     android:id="@+id/recyclerView"     android:layout_width="match_parent"     android:layout_height="match_parent" />
   | 
 
java部分:
TagActivity部分:
主要在于新增tagAdapter,以及数据tagList的获取
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
   |  public class TagActivity extends AppCompatActivity {     private RecyclerView recyclerView;     private TagAdapter tagAdapter;      private List<TagItem> tagList;     @Override     protected void onCreate(Bundle savedInstanceState) {         super.onCreate(savedInstanceState);         setContentView(R.layout.activity_tag);
                   tagList = new ArrayList<>(); 
                   tagAdapter = new TagAdapter(tagList);         recyclerView.setAdapter(tagAdapter);
                   performNetworkRequest();     }      }
 
  | 
 
TagItem部分:
该部分就是提前把需要展示的数据封装为类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
   | public class TagItem {     private String tagName;     private String tagDescription;
      private boolean isDetailsVisible;           public boolean isDetailsVisible() {         return isDetailsVisible;     }     public void setDetailsVisible(boolean visible) {         isDetailsVisible = visible;     }     public TagItem(String tagName, String tagDescription) {         this.tagName = tagName;         this.tagDescription = tagDescription;     }     public String getTagName() {         return tagName;     }     public String getTagDescription() {         return tagDescription;     } }
  | 
 
TagAdapter部分:
该部分的重写方法是内部封装好去重写的方法
首先最开始是去定义在TagAdapter中的全局变量
然后onCreateViewHolder()方法去新增view(注意要另外建立好)
接着是onBindViewHolder是绑定数据(也就是set各种属性)注意这里设定属性有可能会只设置到最后一个元素,原因一般有两种:1、没加notifyDataSetChanged()通知适配器数据已更改   2、试图在方法里去改变属性,因为方法最后只会绑定到最后一个view,应该在外围进行更改
还有getItemCount来确定一共生成多少view
数据来源则是ViewHolder,这里去find各种需要的元素id,然后在onBindViewHolder进行相应操作
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 95 96 97 98 99 100 101 102 103
   | public class TagAdapter extends RecyclerView.Adapter<TagAdapter.ViewHolder> {
      private List<TagItem> tagItemList;     private int visibilityState1 = View.VISIBLE;     private int visibilityState2 = View.GONE;
 
 
      public TagAdapter(List<TagItem> tagItemList) {         this.tagItemList = tagItemList;                  this.visibilityState1 = View.VISIBLE;         this.visibilityState2 = View.GONE;     }
      @NonNull     @Override     public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {         View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_tag, parent, false);         return new ViewHolder(view);     }
      @Override     public void onBindViewHolder(@NonNull ViewHolder holder, int position) {         TagItem tagItem = tagItemList.get(position);         System.out.println(tagItem.getTagName());         holder.tagNameTextView.setText(tagItem.getTagName());         holder.tagDescriptionTextView.setText(tagItem.getTagDescription());
 
 
          holder.navDelete.setOnClickListener(new View.OnClickListener() {             @Override             public void onClick(View v) {                                  visibilityState1 = (visibilityState1 == View.GONE) ? View.VISIBLE : View.GONE;                 visibilityState2 = (visibilityState2 == View.GONE) ? View.VISIBLE : View.GONE;
                                   notifyDataSetChanged();             }         });
                   holder.detailEdit.setVisibility(visibilityState1);                  holder.detailDelete.setVisibility(visibilityState2);
                   if (visibilityState1 == View.VISIBLE) {             animateView(holder.detailEdit, true);         } else {             animateView(holder.detailEdit, false);         }
          if (visibilityState2 == View.VISIBLE) {             animateView(holder.detailDelete, true);         } else {             animateView(holder.detailDelete, false);         }
      }
           private void animateView(View view, boolean show) {         float startAlpha = show ? 0f : 1f;         float endAlpha = show ? 1f : 0f;
          ObjectAnimator alphaAnimator = ObjectAnimator.ofFloat(view, "alpha", startAlpha, endAlpha);         alphaAnimator.setDuration(300); 
          alphaAnimator.start();     }
 
 
      @Override     public int getItemCount() {         return tagItemList.size();     }
      public class ViewHolder extends RecyclerView.ViewHolder {         TextView tagNameTextView;         TextView tagDescriptionTextView;
                   View Nav;         ImageView navDelete;
          CardView detailEdit;         CardView detailDelete;         public ViewHolder(@NonNull View itemView) {             super(itemView);             tagNameTextView = itemView.findViewById(R.id.tagName);             tagDescriptionTextView = itemView.findViewById(R.id.tagDescription);
              Nav= ((Activity)itemView.getContext()).findViewById(R.id.Nav);             navDelete = Nav.findViewById(R.id.navDelete);             detailEdit = itemView.findViewById(R.id.detailEdit);             detailDelete = itemView.findViewById(R.id.detailDelete);         }     } }
  | 
 
ConstraintLayout
相当于融合了LinearLayout和RelativeLayout
下表列出了可用约束的属性列表
| 属性 | 
| layout_constraintLeft_toLeftOf | 
| layout_constraintLeft_toRightOf | 
| layout_constraintRight_toLeftOf | 
| layout_constraintRight_toRightOf | 
| layout_constraintTop_toTopOf | 
| layout_constraintTop_toBottomOf | 
| layout_constraintBottom_toTopOf | 
| layout_constraintBottom_toBottomOf | 
| layout_constraintBaseline_toBaselineOf | 
| layout_constraintStart_toEndOf | 
| layout_constraintStart_toStartOf | 
| layout_constraintEnd_toStartOf | 
| layout_constraintEnd_toEndOf | 
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
   | <?xml version="1.0" encoding="utf-8"?> <androidx.drawerlayout.widget.DrawerLayout 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=".TagActivity"     android:id="@+id/drawerLayout">     <androidx.constraintlayout.widget.ConstraintLayout         android:layout_width="match_parent"         android:layout_height="match_parent"         android:orientation="vertical"         android:padding="15dp">         <include android:id="@+id/Nav" layout="@layout/activity_nav"/>
          <androidx.recyclerview.widget.RecyclerView             android:id="@+id/recyclerView"             android:layout_width="match_parent"             android:layout_height="0dp"             app:layout_constraintTop_toBottomOf="@id/Nav"             app:layout_constraintStart_toStartOf="parent"             app:layout_constraintEnd_toEndOf="parent"             app:layout_constraintBottom_toBottomOf="parent"/>         <androidx.cardview.widget.CardView             android:id="@+id/cardView"             android:layout_width="70dp"             android:layout_height="70dp"             app:cardCornerRadius="40dp"             app:cardElevation="0dp"             android:layout_marginTop="0dp"             app:layout_constraintEnd_toEndOf="parent"             app:layout_constraintBottom_toBottomOf="parent"             app:layout_constraintHorizontal_bias="1.0">
              <TextView                 android:layout_width="match_parent"                 android:layout_height="match_parent"                 android:text="+"                 android:textSize="20sp"                 android:textStyle="bold"                 android:gravity="center"                 android:textColor="@color/white"                 android:background="@color/zi" />         </androidx.cardview.widget.CardView>     </androidx.constraintlayout.widget.ConstraintLayout>     <com.google.android.material.navigation.NavigationView         android:id="@+id/drawerMenu"         android:layout_width="210dp"         android:layout_height="match_parent"         android:layout_gravity="start">         <include             layout="@layout/activity_drawer_menu"/>     </com.google.android.material.navigation.NavigationView> </androidx.drawerlayout.widget.DrawerLayout>
   | 
 
EditView
用于文字的输入
hint用于提示文字,maxLength为最长允许输入长度,
background=”@null”很关键,可以去除掉hint的下划线
1 2 3 4 5 6 7 8 9 10
   | <EditText     android:layout_width="wrap_content"     android:layout_height="wrap_content"     android:hint="请输入名称"     android:maxLength="6"     android:textStyle="bold"     android:textColor="@color/balck"     android:hitColor="@color/hui"     android:textSize="15sp"     android:background="@null"/>
   | 
 
在java中获取文字
注意赋值给String类型的变量是要toString()
1
   | userEmail=userEmailEditText.getText().toString();
   | 
 
基本属性
视图宽高
match_parent:与父级视图保持一致
wrap_content:表示与内容自适应
以dp为单位的具体尺寸
间距
外边距:layout_margin
内边距:padding
对齐方式
指定当前视图相对于上级视图的对齐方式:layout_gravity
指定下级视图相对于当前视图的对齐方式:gravity
固定左上角:left|top
排列方式
使用orientation属性控制排列方式,默认水平排列
水平:orientation:horizontal
垂直:orientation:vertical
权重
使用layout_weight属性控制权重,相当于各自拥有多大比例
Layout_width为0dp时,layout_weight表示水平方向的宽度比例
Layout_height为0dp时,layout_weight表示垂直方向的宽度比例
对可见性的处理
使用Visibility来到达使用同一个xml达成不同布局的效果,能够优化代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
   | public class MainActivity extends AppCompatActivity {     @Override     protected void onCreate(Bundle savedInstanceState) {         super.onCreate(savedInstanceState);         setContentView(R.layout.activity_main);
                   View drawerMenu1 = findViewById(R.id.drawerMenu1);
                   CardView drawerMenuPoint = drawerMenu1.findViewById(R.id.drawerMenuPoint);         CardView drawerMenuAvatar = drawerMenu1.findViewById(R.id.drawerMenuAvatar);
                   drawerMenuPoint.setVisibility(View.GONE);         drawerMenuAvatar.setVisibility(View.GONE);     } }
  | 
 
基础操作
调试
在Logcat里查看调试信息
Log.v 的调试颜色为黑色的,任何消息都会输出,这里的v代表verbose啰嗦的意思,平时使用就是Log.v(“”,””);
Log.d的输出颜色是蓝色的,仅输出debug调试的意思,但他会输出上层的信息,过滤起来可以通过DDMS的Logcat标签来选择.
Log.i的输出为绿色,一般提示性的消息information,它不会输出Log.v和Log.d的信息,但会显示i、w和e的信息
Log.w的意思为橙色,可以看作为warning警告,一般需要我们注意优化Android代码,同时选择它后还会输出Log.e的信息。
Log.e为红色,可以想到error错误,这里仅显示红色的错误信息,这些错误就需要我们认真的分析,查看栈的信息了。
实践效果
导航跳转页面
下面封装了代码,关键代码在自定义方法startActivity中
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
   |  public class DrawerMenuHelper {     private AppCompatActivity activity;
      public DrawerMenuHelper(AppCompatActivity activity) {         this.activity = activity;     }
      public void setupDrawerMenu(int num) {       	         LinearLayout drawerMenuTo1=navigationView.findViewById(drawerMenuToBIds[0]);
          drawerMenuTo1.setOnClickListener(new View.OnClickListener() {             @Override             public void onClick(View view) {                 startActivity(MainActivity.class);                 Log.v("drawerMenu","点击抽屉的第一个按钮");             }         });     }   	     private void startActivity(Class<?> cls) {         Intent intent = new Intent(activity, cls);         activity.startActivity(intent);         activity.finish();      } }
  public class MainActivity extends AppCompatActivity {     @Override     protected void onCreate(Bundle savedInstanceState) {         super.onCreate(savedInstanceState);         setContentView(R.layout.activity_main);
          DrawerMenuHelper drawerMenuHelper = new DrawerMenuHelper(this);         drawerMenuHelper.setupDrawerMenu(0);     } }
 
  | 
 
网络请求
使用okhttp3框架
首先要在build.gradle进行引入implementation(“com.squareup.okhttp3:okhttp:4.9.1”)
其次是在AndroidManifest.xml加入权限
1 2 3
   | <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
   | 
 
然后编写请求的逻辑这里要注意数据的格式、请求的方法、返回数据的格式(具体去查看swiftui笔记里的网络请求部分)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
   | private void performNetworkRequest() {          OkHttpClient client = new OkHttpClient();               String url = "https://tengenchang.top/tag/get";               String requestData = "3489044730@qq.com";               MediaType JSON = MediaType.parse("application/json; charset=utf-8");     RequestBody requestBody = RequestBody.create(JSON, requestData);               Request request = new Request.Builder()             .url(url)             .post(requestBody)             .build();                }
  | 
 
接下来首先要把网络请求放在子线程里,本来是使用写一个类继承AsyncTask,然后在主线程中使用execute()方法来调用子线程,但是execute()方法,以及在主线程更新ui的onPostExecute()方法已经在API30中被弃用(卡了我一整节习概QAQ)解决方法就是使用okhttp3的onResponse()方法内的runOnUiThread()方法去在更新ui
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
   | private void performNetworkRequest() {   	          client.newCall(request).enqueue(new Callback() {         @Override         public void onResponse(Call call, Response response) throws IOException {             if (response.isSuccessful()) {                                  String responseBody = response.body().string();                 try {                                          JSONObject jsonResponse = new JSONObject(responseBody);                     JSONArray data = jsonResponse.getJSONArray("data");
                                           tagList.clear();
                                           for (int i = 0; i < data.length(); i++) {                         JSONObject item = data.getJSONObject(i);                         String tagName = item.getString("tagName");                         String tagDescribe = item.getString("tagDescribe");
                                                   tagList.add(new TagItem(tagName, tagDescribe));                     }
                                           runOnUiThread(new Runnable() {                         @Override                         public void run() {                                                          tagAdapter.notifyDataSetChanged();                         }                     });
                  } catch (JSONException e) {                     e.printStackTrace();                 }             } else {                                  Log.e("TagActivity", "请求失败,状态码: " + response.code());                 Log.e("TagActivity", response.body().string());             }         }
          @Override         public void onFailure(Call call, IOException e) {             e.printStackTrace();         }     }); }
  | 
 
RelativeLayout内的适配器只能修改单一View的问题
原因一般有两种:1、没加notifyDataSetChanged()通知适配器数据已更改   2、试图在方法里去改变属性,因为方法最后只会绑定到最后一个view,应该在外围进行更改(具体源代码可以去看简单空间部分的RelativeLayout介绍,这个问题也卡了挺久QAQ)
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 95 96 97 98 99 100 101 102 103
   | public class TagAdapter extends RecyclerView.Adapter<TagAdapter.ViewHolder> {
      private List<TagItem> tagItemList;     private int visibilityState1 = View.VISIBLE;     private int visibilityState2 = View.GONE;
 
 
      public TagAdapter(List<TagItem> tagItemList) {         this.tagItemList = tagItemList;                  this.visibilityState1 = View.VISIBLE;         this.visibilityState2 = View.GONE;     }
      @NonNull     @Override     public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {         View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_tag, parent, false);         return new ViewHolder(view);     }
      @Override     public void onBindViewHolder(@NonNull ViewHolder holder, int position) {         TagItem tagItem = tagItemList.get(position);         System.out.println(tagItem.getTagName());         holder.tagNameTextView.setText(tagItem.getTagName());         holder.tagDescriptionTextView.setText(tagItem.getTagDescription());
 
 
          holder.navDelete.setOnClickListener(new View.OnClickListener() {             @Override             public void onClick(View v) {                                  visibilityState1 = (visibilityState1 == View.GONE) ? View.VISIBLE : View.GONE;                 visibilityState2 = (visibilityState2 == View.GONE) ? View.VISIBLE : View.GONE;
                                   notifyDataSetChanged();             }         });
                   holder.detailEdit.setVisibility(visibilityState1);                  holder.detailDelete.setVisibility(visibilityState2);
                   if (visibilityState1 == View.VISIBLE) {             animateView(holder.detailEdit, true);         } else {             animateView(holder.detailEdit, false);         }
          if (visibilityState2 == View.VISIBLE) {             animateView(holder.detailDelete, true);         } else {             animateView(holder.detailDelete, false);         }
      }
           private void animateView(View view, boolean show) {         float startAlpha = show ? 0f : 1f;         float endAlpha = show ? 1f : 0f;
          ObjectAnimator alphaAnimator = ObjectAnimator.ofFloat(view, "alpha", startAlpha, endAlpha);         alphaAnimator.setDuration(300); 
          alphaAnimator.start();     }
 
 
      @Override     public int getItemCount() {         return tagItemList.size();     }
      public class ViewHolder extends RecyclerView.ViewHolder {         TextView tagNameTextView;         TextView tagDescriptionTextView;
                   View Nav;         ImageView navDelete;
          CardView detailEdit;         CardView detailDelete;         public ViewHolder(@NonNull View itemView) {             super(itemView);             tagNameTextView = itemView.findViewById(R.id.tagName);             tagDescriptionTextView = itemView.findViewById(R.id.tagDescription);
              Nav= ((Activity)itemView.getContext()).findViewById(R.id.Nav);             navDelete = Nav.findViewById(R.id.navDelete);             detailEdit = itemView.findViewById(R.id.detailEdit);             detailDelete = itemView.findViewById(R.id.detailDelete);         }     } }
  | 
 
删除指定页面
最大的问题在于如何删除,以及如何通知主线程去更改ui,以及使用getcontext来找到父activity
注意一下getcontext的用法
View类中提供的方法,在继承了View的类中才可以调用。
返回的是当前View运行在哪个Activity Contex中,获取当前context的实例。
如果使用场景是Activity则相当于 this
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
   | private void deleteTarget(TargetItem targetItem, int position, Context context) {          OkHttpClient client = new OkHttpClient();               String url = "https://tengenchang.top/target/delete";     System.out.println("targetId:" + targetItem.getTargetId());               JSONObject requestData = new JSONObject();     try {         requestData.put("userEmail", "3489044730@qq.com");         requestData.put("targetName", targetItem.getTargetName());         requestData.put("ifPoints", 0);         requestData.put("targetId", Long.valueOf(targetItem.getTargetId()));     } catch (JSONException e) {         e.printStackTrace();     }               MediaType JSON = MediaType.parse("application/json; charset=utf-8");     RequestBody requestBody = RequestBody.create(JSON, requestData.toString());               Request request = new Request.Builder()             .url(url)             .post(requestBody)             .build();               client.newCall(request).enqueue(new Callback() {         @Override         public void onResponse(Call call, Response response) throws IOException {             if (response.isSuccessful()) {                                  targetItemList.remove(position);                                                   ((Activity) context).runOnUiThread(new Runnable() {                     @Override                     public void run() {                         notifyItemRemoved(position);                     }                 });                                                   ((Activity) context).runOnUiThread(new Runnable() {                     @Override                     public void run() {                         notifyItemRangeChanged(position, targetItemList.size());                     }                 });             } else {                                  Log.e("TargetActivity", "请求失败,状态码: " + response.code());                 Log.e("TargetActivity", response.body().string());             }         }
          @Override         public void onFailure(Call call, IOException e) {             e.printStackTrace();         }     }); }
  | 
 
edit和delete转化
第一种情况
页面里只有一个RelativeLayout,无论在adapter里实现点击事件还是在activity中实现点击事件都可以,详细内容可见RelativeLayout内的适配器只能修改单一View的问题
第二种情况(又卡住QAQ)
页面中有两个RelativeLayout,那就不能在adapter中实现事件,因为最后只会实现最后一个点击事件,这时就需要在activity中实现
TargetActivity:
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
   | public class TargetActivity extends AppCompatActivity {     private RecyclerView targetWithTimeRecyclerView;     private RecyclerView targetNoTimeRecyclerView;     private TargetWithTimeAdapter targetWithTimeAdapter;     private TargetNoTimeAdapter targetNoTimeAdapter;     private List<TargetItem> targetWithTimeList;     private List<TargetItem> targetNoTimeList;
      private int targetVisibilityState1 = View.VISIBLE;     private int targetVisibilityState2 = View.GONE;
 
      private View Nav;     ImageView navDelete;
 
      @Override     protected void onCreate(Bundle savedInstanceState) {         super.onCreate(savedInstanceState);         setContentView(R.layout.activity_target);                  Nav = findViewById(R.id.Nav);         navDelete = Nav.findViewById(R.id.navDelete);
          navDelete.setOnClickListener(new View.OnClickListener() {             @Override             public void onClick(View v) {                                  targetVisibilityState1 = (targetVisibilityState1 == View.GONE) ? View.VISIBLE : View.GONE;                 targetVisibilityState2 = (targetVisibilityState2 == View.GONE) ? View.VISIBLE : View.GONE;
                                   targetNoTimeAdapter.updateVisibility(targetVisibilityState1, targetVisibilityState2);                 targetWithTimeAdapter.updateVisibility(targetVisibilityState1, targetVisibilityState2);             }         });                  targetWithTimeRecyclerView = findViewById(R.id.targetWithTimeRecyclerView);         targetNoTimeRecyclerView = findViewById(R.id.targetNoTimeRecyclerView);         targetWithTimeRecyclerView.setLayoutManager(new LinearLayoutManager(this));         targetNoTimeRecyclerView.setLayoutManager(new LinearLayoutManager(this));
                   targetWithTimeList = new ArrayList<>();          targetNoTimeList = new ArrayList<>(); 
                   targetWithTimeAdapter = new TargetWithTimeAdapter(targetWithTimeList,targetVisibilityState1, targetVisibilityState2);         targetNoTimeAdapter = new TargetNoTimeAdapter(targetNoTimeList,targetVisibilityState1, targetVisibilityState2);
          targetWithTimeRecyclerView.setAdapter(targetWithTimeAdapter);         targetNoTimeRecyclerView.setAdapter(targetNoTimeAdapter);              } }
  | 
 
targetNoTimeAdapter
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
   | public class TargetNoTimeAdapter extends RecyclerView.Adapter<TargetNoTimeAdapter.ViewHolder>{     private List<TargetItem> targetItemList;     private int targetNoTimeVisibilityState1 = View.VISIBLE;     private int targetNoTimeVisibilityState2= View.GONE;
      public TargetNoTimeAdapter(List<TargetItem> targetItemList, int visibilityState1, int visibilityState2) {         this.targetItemList = targetItemList;                  this.targetNoTimeVisibilityState1 = visibilityState1;         this.targetNoTimeVisibilityState2 = visibilityState2;     }
      @NonNull     @Override     public TargetNoTimeAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {         View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_target_notime, parent, false);         return new TargetNoTimeAdapter.ViewHolder(view);     }
      @Override     public void onBindViewHolder(@NonNull TargetNoTimeAdapter.ViewHolder holder, int position) {         TargetItem targetItem = targetItemList.get(position);         System.out.println(targetItem.getTargetName());         holder.targetNameTextView.setText(targetItem.getTargetName());         holder.targetDescriptionTextView.setText(targetItem.getTargetDescribe());         holder.targetNoTimePointTextView.setText("X"+targetItem.getTargetPoint());
 
                   holder.targetNoTimePointCardView.setVisibility(targetNoTimeVisibilityState1);         holder.targetNoTimeDayDifference.setVisibility(targetNoTimeVisibilityState1);                  holder.targetNoTimeDelete.setVisibility(targetNoTimeVisibilityState2);     }     public void updateVisibility(int visibilityState1, int visibilityState2) {         targetNoTimeVisibilityState1 = visibilityState1;         targetNoTimeVisibilityState2 = visibilityState2;         notifyDataSetChanged();     }
      @Override     public int getItemCount() {         return targetItemList.size();     }
      public class ViewHolder extends RecyclerView.ViewHolder {         TextView targetNameTextView;         TextView targetDescriptionTextView;         TextView targetNoTimePointTextView;
                   View Nav;         ImageView navDelete;
          CardView targetNoTimePointCardView;         CardView targetNoTimeDelete;         TextView targetNoTimeDayDifference;
          public ViewHolder(@NonNull View itemView) {             super(itemView);             targetNameTextView = itemView.findViewById(R.id.targetNoTimeName);             targetDescriptionTextView = itemView.findViewById(R.id.targetNoTimeDescribe);             targetNoTimePointTextView = itemView.findViewById(R.id.targetNoTimePoint);
              Nav = ((Activity) itemView.getContext()).findViewById(R.id.Nav);             navDelete = Nav.findViewById(R.id.navDelete);             targetNoTimePointCardView = itemView.findViewById(R.id.targetNoTimePointCardView);             targetNoTimeDelete = itemView.findViewById(R.id.targetNoTimeDelete);             targetNoTimeDayDifference = itemView.findViewById(R.id.targetNoTimeDayDifference);         }     } }
  | 
 
日期创建
这块涉及的比较多,有时间再仔细看一下
知识点不只是日期的相应处理,还有使用java去构建布局,这一点我都使用的都比较简单,但是下面的代码是比较复杂布局构建,但是其实复杂布局就是去记住更多的布局对象的相应属性
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 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
   | private View createDateItemView(final int index, final List<TargetItem> targetWithTimeList) {          Date currentDate = calendar.getTime();          calendar.add(Calendar.DAY_OF_MONTH, index);          Date date = calendar.getTime();          calendar.setTime(currentDate);
           SimpleDateFormat dayOfWeekFormat = new SimpleDateFormat("E");     SimpleDateFormat dayOfMonthFormat = new SimpleDateFormat("d");
           LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(             LinearLayout.LayoutParams.WRAP_CONTENT,             LinearLayout.LayoutParams.WRAP_CONTENT     );     layoutParams.setMargins(18, 0, 18, 0);
           RelativeLayout dateItemLayout = new RelativeLayout(this);     dateItemLayout.setLayoutParams(layoutParams);
           TextView dayOfWeekTextView = new TextView(this);     dayOfWeekTextView.setText(dayOfWeekFormat.format(date));     dayOfWeekTextView.setId(View.generateViewId());     dayOfWeekTextView.setTextColor(Color.GRAY);     dayOfWeekTextView.setTextSize(12);
           RelativeLayout.LayoutParams dayOfWeekParams = new RelativeLayout.LayoutParams(             RelativeLayout.LayoutParams.WRAP_CONTENT,             RelativeLayout.LayoutParams.WRAP_CONTENT     );     dayOfWeekParams.addRule(RelativeLayout.CENTER_HORIZONTAL);     dayOfWeekTextView.setLayoutParams(dayOfWeekParams);
           TextView dayOfMonthTextView = new TextView(this);     dayOfMonthTextView.setText(dayOfMonthFormat.format(date));     dayOfMonthTextView.setWidth(getResources().getDimensionPixelSize(R.dimen.date_item_width));     dayOfMonthTextView.setHeight(getResources().getDimensionPixelSize(R.dimen.date_item_height));     dayOfMonthTextView.setGravity(Gravity.CENTER);
           if (index == 0) {         dayOfMonthTextView.setTextColor(Color.parseColor("#CFC8FF"));         dayOfMonthTextView.setBackgroundResource(R.drawable.selected_date_background);         lastSelectedDayTextView = dayOfMonthTextView;     } else {         dayOfMonthTextView.setTextColor(Color.parseColor("#CFC8FF"));         dayOfMonthTextView.setBackgroundResource(R.drawable.unselected_date_background);     }
           RelativeLayout.LayoutParams dayOfMonthParams = new RelativeLayout.LayoutParams(             RelativeLayout.LayoutParams.WRAP_CONTENT,             RelativeLayout.LayoutParams.WRAP_CONTENT     );     dayOfMonthParams.addRule(RelativeLayout.CENTER_HORIZONTAL);     dayOfMonthParams.addRule(RelativeLayout.BELOW, dayOfWeekTextView.getId());     dayOfMonthTextView.setLayoutParams(dayOfMonthParams);
           dayOfMonthTextView.setClickable(true);
                dayOfMonthTextView.setOnClickListener(new View.OnClickListener() {         @Override         public void onClick(View v) {             if (lastSelectedDayTextView != null) {                                  lastSelectedDayTextView.setBackgroundResource(R.drawable.unselected_date_background);                 lastSelectedDayTextView.setTextColor(Color.parseColor("#CFC8FF"));             }
                           dayOfMonthTextView.setBackgroundResource(R.drawable.selected_date_background);             dayOfMonthTextView.setTextColor(Color.parseColor("#CFC8FF"));
                           lastSelectedDayTextView = dayOfMonthTextView;             System.out.println("lastSelectedDayTextView:" + lastSelectedDayTextView);
                           String selectedDate = new SimpleDateFormat("yyyy-MM-dd").format(date);
                           for (int i = 0; i < targetWithTimeList.size(); i++) {                 TargetItem targetItem = targetWithTimeList.get(i);                 String deadline = targetItem.getDeadline(); 
                                   String[] deadlineParts = deadline.split("T");                 String deadlineDate = deadlineParts[0];                  String deadlineTime = deadlineParts[1].substring(0, 5); 
                                   long dayDifference = calculateDayDifference(selectedDate, deadlineDate);
                                   if (dayDifference > 0) {                                          targetItem.setDayDifference(dayDifference + "天");                 } else if (dayDifference == 0) {                                          targetItem.setDayDifference(deadlineTime);                 } else {                                          targetItem.setDayDifference(deadlineDate.substring(5));                 }                 System.out.println("deadlineTime:" + targetItem.getDayDifference());                                  targetWithTimeAdapter.notifyDataSetChanged();             }         }     });
           dateItemLayout.addView(dayOfWeekTextView);     dateItemLayout.addView(dayOfMonthTextView);
           return dateItemLayout; }
  | 
 
RecyclerView适配器根据条件转成不同的页面
这里的实现效果,我之前一直是采用多个RecyclerView来达成条件转成的效果,然后可以直接根据一定的条件进行不同的页面,不过下面的例子只实现了list为空时的转化
Adapter部分
注意getItemViewType判断list的size
onCreateViewHolder的if语句来转化不同页面
onBindViewHolder的if语句进行不同处理
getItemCount也是去判断list的size
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
   | public class TagAdapter extends RecyclerView.Adapter<TagAdapter.ViewHolder> {     public TagAdapter(List<TagItem> tagItemList) {         this.tagItemList = tagItemList;     }
      @Override     public int getItemViewType(int position) {         if (tagItemList.size() == 0) {             return 1;          } else {             return 0;          }     }
      @NonNull     @Override     public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {         if (viewType == 0) {             View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_tag, parent, false);             return new TagAdapter.ViewHolder(view);         } else {             View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_tag_null, parent, false);             return new TagAdapter.ViewHolder(view);         }     }
      @Override     public void onBindViewHolder(@NonNull ViewHolder holder, int position) {         if (tagItemList.size() == 0) {             
                       } else {                    }     }     @Override     public int getItemCount() {         if (tagItemList.size() == 0) {             return 1;          } else {             return tagItemList.size();         }     }     public class ViewHolder extends RecyclerView.ViewHolder {         public ViewHolder(@NonNull View itemView) {             super(itemView);         }     } }
 
  | 
 
轮播图实现
使用ViewPager2来实现轮播图,ViewPager2实际上也是RecyclerView
使用handler.postDelayed(runnable, 1800);开始轮播任务
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
   | public class LoginNavActivity extends AppCompatActivity {     private TextView userAgreement;     private TextView privacyPolicy;
      private ViewPager2 viewPager;     private List<CarouselItem> carouselItems = new ArrayList<>();     private int currentItem = 0;      private Handler handler = new Handler();     private Runnable runnable;
      private LinearLayout loginNavLoginLinearLayout;
      @Override     protected void onCreate(Bundle savedInstanceState) {         super.onCreate(savedInstanceState);         setContentView(R.layout.activity_login_nav);
          userAgreement=findViewById(R.id.userAgreement);         privacyPolicy=findViewById(R.id.privacyPolicy);
          userAgreement.setOnClickListener(new View.OnClickListener() {             @Override             public void onClick(View view) {                 startActivity(UserAgreementActivity.class);             }         });         privacyPolicy.setOnClickListener(new View.OnClickListener() {             @Override             public void onClick(View view) {                 startActivity(PrivacyPolicyActivity.class);             }         });
          viewPager = findViewById(R.id.viewPager);
                   carouselItems.add(new CarouselItem(R.drawable.loginnavlogo1, "兑换\n商店积分"));         carouselItems.add(new CarouselItem(R.drawable.loginnavlogo2, "发现\n自我进步"));         carouselItems.add(new CarouselItem(R.drawable.loginnavlogo3, "建立\n计时标签"));         carouselItems.add(new CarouselItem(R.drawable.loginnavlogo4, "建立\n你的目标"));
                   CarouselAdapter carouselAdapter = new CarouselAdapter(carouselItems);         viewPager.setAdapter(carouselAdapter);
                   runnable = new Runnable() {             @Override             public void run() {                 if (currentItem == carouselItems.size() - 1) {                     currentItem = 0;                 } else {                     currentItem++;                 }                 viewPager.setCurrentItem(currentItem);                 handler.postDelayed(this, 1800);              }         };
                   handler.postDelayed(runnable, 1800);
          loginNavLoginLinearLayout=findViewById(R.id.loginNavLogin);         loginNavLoginLinearLayout.setOnClickListener(new View.OnClickListener() {             @Override             public void onClick(View view) {                                  startActivity(HomeActivity.class);             }         });     }
      @Override     protected void onDestroy() {         super.onDestroy();                  handler.removeCallbacks(runnable);     }     private void startActivity(Class<?> cls) {         Intent intent = new Intent(this, cls);         this.startActivity(intent);         this.finish();      } }
  | 
 
跳转时传递信息
通过putExtra转递
1 2 3 4 5 6 7
   | private void startActivity(Class<?> cls) {     Intent intent = new Intent(this, cls);   	     intent.putExtra("sourceActivity", "Tag");     startActivity(intent);     finish();  }
  | 
 
获取信息
1 2 3 4 5 6 7 8 9 10
   |  String sourceActivity = getIntent().getStringExtra("sourceActivity");
  if ("Tag".equals(sourceActivity)) {         createNavTitle.setText("建立标签");  } else if ("Store".equals(sourceActivity)) {          createNavTitle.setText("建立商品");    }else if ("Target".equals(sourceActivity)) {          createNavTitle.setText("建立目标");    }
 
  | 
 
计时页面实现
弹窗实现
先创建AlertDialog对象
再通过setTitle以及setMessage以及setPositiveButton以及setNegativeButton来设置相应的内容
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
   | private void cancelTimer() {     if (countDownTimer != null) {                  AlertDialog.Builder builder = new AlertDialog.Builder(this);                  builder.setTitle("确定要放弃吗?");                  builder.setMessage("本次计时将不会得到任何分数");                  builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {             @Override             public void onClick(DialogInterface dialog, int which) {                                  countDownTimer.cancel();                 timerTextView.setText(timer);                 isTimerRunning = false;                 timeButtonTextView.setText("开始");             }         });                  builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {             @Override             public void onClick(DialogInterface dialog, int which) {                                  dialog.dismiss();             }         });                  AlertDialog alertDialog = builder.create();         alertDialog.show();     } }
  | 
 
提示框实现
注意这里的context可以取消
1
   | Toast.makeText(context.getApplicationContext(), "完成目标", Toast.LENGTH_SHORT).show();
   |