1.使用Toolbar替换ActionBar,创建项目是默认的actionbar,我们需要一个不带actionbar。
1).默认的actionbar:
>
<!-- Base application theme. -->
>
2).修改后为不带actionbar 可以修改为Theme.AppCompat.Light.NoActionBar和Theme.AppCompat.NoActionBar两种属性前者是淡色主题,后者是深色,我们一般使用淡色主题。
>
<!-- Base application theme. --><!--淡色的toobar-->
>
2.style中的文件
>
<!-- Base application theme. --><!--设置为不要actionbar-->
<!--设置点击toolbar显示在下方-->
>
3.在res下面创建menu的文件夹,然后创建对应的Menu resourcefile文件
选择3个图片,用于显示
<?xml version="1.0" encoding="utf-8"?>
>
package com.example.materialdesign;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar=findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);//标题栏带返回按钮
}
//动态加载标题栏的toolbar
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.toolbarl,menu);
return super.onCreateOptionsMenu(menu);
}
//多个toobar选中是点的哪一个
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
switch (item.getItemId()){
case R.id.backup:
Toast.makeText(this,"点击了返回",Toast.LENGTH_SHORT).show();
break;
case R.id.delete:
Toast.makeText(this,"点击了删除",Toast.LENGTH_SHORT).show();
break;
case R.id.settings:
Toast.makeText(this,"点击了设置",Toast.LENGTH_SHORT).show();
break;
}
return true;
}
}
//toolbar中显示图标
@SuppressLint("RestrictedApi")
@Override
protected boolean onPrepareOptionsPanel(View view, Menu menu) {
if (menu != null) {
if (menu.getClass() == MenuBuilder.class) {
try {
//利用反射获取私有方法
Method m = menu.getClass().getDeclaredMethod("setOptionalIconsVisible", Boolean.TYPE);
m.setAccessible(true);
m.invoke(menu, true);
} catch (Exception e) {
e.printStackTrace();
}
}
}
return super.onPrepareOptionsPanel(view, menu);
}
5.layout文件
:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="@color/colorPrimary"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="@style/ToolBarPopupThem"
tools:ignore="MissingConstraints"> >
1.加粗样式1.layout文件中:
DrawerLayout内部第一个控件为显示界面,第二个控件为滑动弹出,并且第一个控件设置的是标题,所以需要一个控件来承载,第二个控件一定要记得android:layout_gravity="start"属性,设置左滑动还是有滑动显示
<?xml version="1.0" encoding="utf-8"?>
: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">
<!--滑动侧边栏-->
>
2.但是用户可能不知道左侧有东西,所以我们可以通过在标题栏上设置一个按钮。
活动中调用
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar=findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
//getSupportActionBar().setDisplayHomeAsUpEnabled(true);//标题栏带返回按钮
//滑动菜单栏可以通过标题栏左边打开
drawerLayout=findViewById(R.id.drawer_laout);
ActionBar actionBar=getSupportActionBar();
if(actionBar!=null){
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setHomeAsUpIndicator(R.drawable.left_menu);
}
}
//多个toobar选中是点的哪一个
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
switch (item.getItemId()){
case R.id.backup:
Toast.makeText(this,"点击了返回",Toast.LENGTH_SHORT).show();
break;
case R.id.delete:
Toast.makeText(this,"点击了删除",Toast.LENGTH_SHORT).show();
break;
case R.id.settings:
Toast.makeText(this,"点击了设置",Toast.LENGTH_SHORT).show();
break;
//标题栏左边ID永远为android.R.id.home
case android.R.id.home:
drawerLayout.openDrawer(GravityCompat.START);//显示隐藏的内容
break;
}
return true;
}
1.引入两个库文件
//优化侧边栏的库
implementation 'com.android.support:design:28.0.0'
//对图片进行处理
implementation 'de.hdodenhof:circleimageview:2.1.0'
<?xml version="1.0" encoding="utf-8"?>
>
3.header的xml文件
<?xml version="1.0" encoding="utf-8"?>
:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="180dp"
android:background="@color/colorPrimary">
:id="@+id/icon_image"
android:src="@drawable/live2d"
android:layout_centerInParent="true"
android:layout_width="70dp"
android:layout_height="70dp"> >
:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/mail"
android:layout_alignParentBottom="true"
android:textColor="#FFF"
android:textSize="14sp"
android:text="[email protected]"> >
:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/username"
android:layout_above="@+id/mail"
android:textColor="#FFF"
android:textSize="14sp"
android:text="王长印"> >
>
4.主布局文件引入
<?xml version="1.0" encoding="utf-8"?>
: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">
<!--滑动侧边栏-->
:id="@+id/nav_view"
android:layout_gravity="start"
app:menu="@menu/nav_menu"
app:headerLayout="@layout/nav_header"
android:layout_width="match_parent"
android:layout_height="match_parent"> >
>
>
5.侧边栏的监听事件
final NavigationView navigationView=findViewById(R.id.nav_view);
navigationView.setCheckedItem(R.id.nav_call);//打开侧边栏默认选中菜单
//菜单栏的监听事件
navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {
navigationView.setCheckedItem(menuItem.getItemId());//点击的菜单设置为选中
Toast.makeText(MainActivity.this,"点击了"+menuItem.getTitle(),Toast.LENGTH_SHORT).show();
return false;
}
});
1.layout文件
<!--悬浮框-->
2.活动(activit)中的监听事件
//悬浮框的监听
FloatingActionButton floatingActionButton= findViewById(R.id.float_ok);
floatingActionButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this,"点击了悬浮框",Toast.LENGTH_SHORT).show();
}
});
//Snackbar的用法
Snackbar.make(view,"This is 悬浮框",Snackbar.LENGTH_SHORT)
.setAction("Sure", new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this,"点击了悬浮框",Toast.LENGTH_SHORT).show();
}
})
.show();
由于使用了上面的Snackbar,悬浮框会被挡住,我们可以借助CoordinatorLayout来让悬浮框向上移动,提示一结束又移动下来。
1.用法:
:layout_width="match_parent"
android:layout_height="match_parent">
<!--标题-->
>
七.卡片式布局(CardView)
1.cardView配合RecycleView使用。
2.引入依赖。
implementation 'androidx.recyclerview:recyclerview:1.1.0'//引入recyclerview
implementation 'androidx.cardview:cardview:1.0.0' //卡片式布局
implementation 'com.github.bumptech.glide:glide:3.7.0' //对图片加载
3.main的layout文件引入recyclerview:recyclerview
:layout_width="match_parent"
android:layout_height="match_parent">
<!--标题-->
<!--引入RecyclerView-->
<!--悬浮框-->
>
4.一个RecyclerView的item类
package com.example.materialdesign.recycle;
public class Fruit {
private String name;
private int imageId;
public Fruit() {
}
public Fruit(String name, int imageId) {
this.name = name;
this.imageId = imageId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getImageId() {
return imageId;
}
public void setImageId(int imageId) {
this.imageId = imageId;
}
}
5…item 的layout文件
<?xml version="1.0" encoding="utf-8"?>
<!--这个要在最外层-->
6.对应的适配器.
package com.example.materialdesign.recycle;
import android.content.Context;
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.cardview.widget.CardView;
import androidx.recyclerview.widget.RecyclerView;
import com.bumptech.glide.Glide;
import com.example.materialdesign.R;
import java.util.List;
public class FruitAdapter extends RecyclerView.Adapter> {
private Context mContext;
private List> mFruitList;
static class ViewHolder extends RecyclerView.ViewHolder{
CardView cardView;
ImageView imageView;
TextView textView;
public ViewHolder(@NonNull View view) {
super(view);
cardView=(CardView)view;
imageView=view.findViewById(R.id.fruit_image);
textView=view.findViewById(R.id.fruit_name);
}
}
public FruitAdapter(List> list){
mFruitList=list;
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
if(mContext == null){
mContext=parent.getContext();
}
View view = LayoutInflater.from(mContext).inflate(R.layout.fruit_ite, parent, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
Fruit fruit=mFruitList.get(position);
holder.textView.setText(fruit.getName());
Glide.with(mContext).load(fruit.getImageId()).into(holder.imageView);
}
@Override
public int getItemCount() {
return mFruitList.size();
}
}
7.活动中:
//引入数据
private Fruit[] fruits={new Fruit("apple",R.drawable.live2d),
new Fruit("Orange",R.drawable.live2d),
new Fruit("Banana",R.drawable.live2d),
new Fruit("Watermelon",R.drawable.live2d),
new Fruit("Pear",R.drawable.live2d),
new Fruit("Cherry",R.drawable.live2d)
};
private List> fruitList=new ArrayList<>();
private FruitAdapter adapter;
//卡片式布局与RecyclerView
initFruit();
RecyclerView recyclerView=findViewById(R.id.recycle_view);
GridLayoutManager layoutManager=new GridLayoutManager(this,2);
recyclerView.setLayoutManager(layoutManager);
adapter=new FruitAdapter(fruitList);
recyclerView.setAdapter(adapter);
private void initFruit() {
fruitList.clear();
//随机生成50个
for(int i=0;i<50;i++){
Random random=new Random();
int index=random.nextInt(fruits.length);
fruitList.add(fruits[index]);
}
}
8.存在的问题:
这样会把标题栏给遮住了,所以可以通过下面来解决
出现把标题栏遮挡的原因:
由于RecyclerView的外层是CoordinatorLayout,CoordinatorLayout是一个加强版的Frament,标题栏和RecyclerView所以会出现覆盖现象
1.把标题栏放到AppBarLayout中
:layout_width="match_parent"
android:layout_height="wrap_content">
<!--标题-->
>
2.RecyclerView加一个属性:
<!--引入RecyclerView-->
3.实现向下滚动标题栏隐藏
其实在RecyclerView滚动的时候已经把滚动时间通知给AppBarLayout
只需要加入app:layout_scrollFlags="scroll|enterAlways|snap"属性
:layout_width="match_parent"
android:layout_height="match_parent">
:layout_width="match_parent"
android:layout_height="wrap_content">
<!--标题-->
>
1.在哪个控件需要下拉刷新就在外层包裹
app:layout_behavior="@string/appbar_scrolling_view_behavior"属性要移动SwipeRefreshLayout来,因为RecyclerView是子控件了,这是上面放置标题栏被遮挡的属性。
<!---下拉刷新-->
2.活动中刷新的事件
//刷新
swipeRefresh=findViewById(R.id.swipe_refresh);
swipeRefresh.setColorSchemeColors(R.color.colorPrimary);//设置默认颜色
swipeRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
refreshFruit();
}
});
private void refreshFruit() {
//模拟去网络上请求数据
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
runOnUiThread(new Runnable() {
@Override
public void run() {
initFruit();//初始化数据
adapter.notifyDataSetChanged();//通知适配器数据发生变化
swipeRefresh.setRefreshing(false);//隐藏刷新
}
});
}
}).start();
}
1.CollapsingToolbarLayout必须要有AppBarLayout,而AppBarLayout又必须要CoordinatorLayout。
新建布局文件 (activit_fruit)
NestedScrollView是可以嵌套滚动事件的
<?xml version="1.0" encoding="utf-8"?>
<!--合适的响应位置-->
:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:fitsSystemWindows="true">
<!--让标题栏显示出来 由于CoordinatorLayout的原因,所以需要AppBarLayout-->
<!--水果内容
app:layout_behavior="@string/appbar_scrolling_view_behavior"显示标题-->
>
2.新建活动FruitActivity
package com.example.materialdesign;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import android.content.Intent;
import android.os.Bundle;
import android.view.MenuItem;
import android.widget.ImageView;
import android.widget.TextView;
import com.bumptech.glide.Glide;
import com.google.android.material.appbar.CollapsingToolbarLayout;
public class FruitActivity extends AppCompatActivity {
public static final String FRUIT_NAME="fruit_name";
public static final String FRUIT_IMAGE_ID="fruit_image_id";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fruit);
Intent intent=getIntent();
String fruitName=intent.getStringExtra(FRUIT_NAME);
int fruitImageId=intent.getIntExtra(FRUIT_IMAGE_ID,0);
Toolbar toolbar=findViewById(R.id.toolbar);
CollapsingToolbarLayout collapsingToolbarLayout=findViewById(R.id.collapsing_toolbar);
ImageView fruitImageView=findViewById(R.id.fruit_image_view);
TextView fruitTextView=findViewById(R.id.fruit_content_text);
setSupportActionBar(toolbar);
ActionBar actionBar=getSupportActionBar();
if(actionBar!=null){
actionBar.setDisplayHomeAsUpEnabled(true);//开启返回按钮
}
collapsingToolbarLayout.setTitle(fruitName);
Glide.with(this).load(fruitImageId).into(fruitImageView);//显示图片
String fruitContent=generateFruitContent(fruitName);//显示内容
fruitTextView.setText(fruitContent);
}
//模拟内容
private String generateFruitContent(String fruitName) {
StringBuilder builder=new StringBuilder();
for(int i=0;i<500;i++){
builder.append(fruitName);
}
return builder.toString();
}
//标题栏的监听事件
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()){
case android.R.id.home:
finish();
return true;
}
return super.onOptionsItemSelected(item);
}
}
3.之前的RecyclerView里面设置点击事件跳转
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
if(mContext == null){
mContext=parent.getContext();
}
View view = LayoutInflater.from(mContext).inflate(R.layout.fruit_ite, parent, false);
//点击跳转
final ViewHolder holder=new ViewHolder(view);
holder.cardView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int positon=holder.getAdapterPosition();
Fruit fruit=mFruitList.get(positon);
Intent intent=new Intent(mContext, FruitActivity.class);
intent.putExtra(FruitActivity.FRUIT_NAME,fruit.getName());
intent.putExtra(FruitActivity.FRUIT_IMAGE_ID,fruit.getImageId());
mContext.startActivity(intent);
}
});
return holder;
}
1.在需要图片显示在状态栏加上属性 android:fitsSystemWindows="true"以及其分容器都要加上
2.res下面创建一个values-v21
由于5.0之前没有透明属性,所以新建values-v21的文件夹
3.在values新建styles.xml
<?xml version="1.0" encoding="utf-8"?>
>
<!--android5.0以后特有的属性,声明状态栏为透明-->
>
4.在原始的values →styles.xml里面加上
<!--状态栏透明-->
>
5.在对应的活动使用此主题
:name=".FruitActivity"
android:theme="@style/FruitActivityTheme"> >