目錄
- 說明
- 1.圓形圖片
- 2.網路圖片
- 1.加入依賴包到build.gradle
- 2.在manifests中添加網路訪問權限
- 3.回到MessageFragment.java中加入網路圖片
- 3.下拉重繪,上拉加載
- 1.匯入依賴
- 2.在message.xml中添加SmartRefreshLayout布局
- 3.添加上拉加載下拉重繪代碼
說明
下面的幾個案例都是基于如下的專案,模仿了QQ的界面,集成了Fragment和RecycleView,如何做出這個界面這里就不貼很多代碼了,代碼上傳在了github,在第六講筆記中有制作的方法,可以參考,
貼一張效果圖

專案結構

1.圓形圖片
在很多的地方,比如上述的QQ案例,在我們常使用的QQ界面中,聯系人的頭像都是圓形的,但是在Android Studio的ImageView并沒有內置的方法設定圓角,接下來介紹一下設定圓角的方法,
新建一個類CircleImageView
用來寫一個圓形圖片,可以直接復制使用
package com.hnucm.myapplication;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Shader;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import androidx.annotation.Nullable;
public class CircleImageView extends androidx.appcompat.widget.AppCompatImageView {
//畫筆
private Paint mPaint;
//圓形圖片的半徑
private int mRadius;
//圖片的宿放比例
private float mScale;
public CircleImageView(Context context) {
super(context);
}
public CircleImageView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public CircleImageView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//由于是圓形,寬高應保持一致
int size = Math.min(getMeasuredWidth(), getMeasuredHeight());
mRadius = size / 2;
setMeasuredDimension(size, size);
}
@SuppressLint("DrawAllocation")
@Override
protected void onDraw(Canvas canvas) {
mPaint = new Paint();
Drawable drawable = getDrawable();
if (null != drawable) {
Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap();
//初始化BitmapShader,傳入bitmap物件
BitmapShader bitmapShader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
//計算縮放比例
mScale = (mRadius * 2.0f) / Math.min(bitmap.getHeight(), bitmap.getWidth());
Matrix matrix = new Matrix();
matrix.setScale(mScale, mScale);
bitmapShader.setLocalMatrix(matrix);
mPaint.setShader(bitmapShader);
//畫圓形,指定好坐標,半徑,畫筆
canvas.drawCircle(mRadius, mRadius, mRadius, mPaint);
} else {
super.onDraw(canvas);
}
}
}
把原來布局中的ImageView改成包名.CircleImageView
2.網路圖片
學會使用開源代碼,最大的同性交友網站github是我們程式員的首選,
網路圖片開源代碼:https://github.com/bumptech/glide
1.加入依賴包到build.gradle
在這個檔案的dependencies下方加入依賴,
implementation 'com.github.bumptech.glide:glide:4.12.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.12.0'

2.在manifests中添加網路訪問權限
因為網路圖片需要獲得網路權限,所以需要添加,
其他地理位置權限,讀取用戶的相冊等等權限都需要在這里添加

android:usesCleartextTraffic 這句代碼意思是如果訪問的地址是http開頭也可以訪問,沒有加就無法訪問,https開頭的地址可以不用加,
3.回到MessageFragment.java中加入網路圖片
核心代碼,用于加載網路圖片
Glide.with(getActivity()).load("https://p3.ssl.qhimgs1.com/sdr/400__/t0188e5449327de5e33.jpg").into(holder.imageView);

3.下拉重繪,上拉加載
開源代碼:https://github.com/scwang90/SmartRefreshLayout
1.匯入依賴
// 注意:分包之后不會有默認的Header和Footer需要手動添加!還是原來的三種方法!
implementation 'com.scwang.smart:refresh-layout-kernel:2.0.3' //核心必須依賴
implementation 'com.scwang.smart:refresh-header-classics:2.0.3' //經典重繪頭
implementation 'com.scwang.smart:refresh-header-radar:2.0.3' //雷達重繪頭
implementation 'com.scwang.smart:refresh-header-falsify:2.0.3' //虛擬重繪頭
implementation 'com.scwang.smart:refresh-header-material:2.0.3' //谷歌重繪頭
implementation 'com.scwang.smart:refresh-header-two-level:2.0.3' //二級重繪頭
implementation 'com.scwang.smart:refresh-footer-ball:2.0.3' //球脈沖加載
implementation 'com.scwang.smart:refresh-footer-classics:2.0.3' //經典加載
同樣要點擊同步
2.在message.xml中添加SmartRefreshLayout布局
SmartRefreshLayout就是

里面嵌套了之前的RecyclerView
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#cccccc"
tools:context=".MessageFragment">
<com.scwang.smart.refresh.layout.SmartRefreshLayout
android:id="@+id/SmartRefreshLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</com.scwang.smart.refresh.layout.SmartRefreshLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
3.添加上拉加載下拉重繪代碼
開源代碼里有樣例
RefreshLayout refreshLayout = (RefreshLayout)findViewById(R.id.refreshLayout);
refreshLayout.setRefreshHeader(new ClassicsHeader(this));
refreshLayout.setRefreshFooter(new ClassicsFooter(this));
refreshLayout.setOnRefreshListener(new OnRefreshListener() {
@Override
public void onRefresh(RefreshLayout refreshlayout) {
refreshlayout.finishRefresh(2000/*,false*/);//傳入false表示重繪失敗
}
});
refreshLayout.setOnLoadMoreListener(new OnLoadMoreListener() {
@Override
public void onLoadMore(RefreshLayout refreshlayout) {
refreshlayout.finishLoadMore(2000/*,false*/);//傳入false表示加載失敗
}
});
這個時候可以實作簡單的重繪了,但是資料沒有發生任何變化
在每次重繪之后清除資料,然后重新添加新資料
在MessageFragment.java中修改

每次上拉之后添加資料

完整代碼
package com.hnucm.myapplication;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import com.bumptech.glide.Glide;
import com.scwang.smart.refresh.footer.ClassicsFooter;
import com.scwang.smart.refresh.header.ClassicsHeader;
import com.scwang.smart.refresh.layout.SmartRefreshLayout;
import com.scwang.smart.refresh.layout.api.RefreshLayout;
import com.scwang.smart.refresh.layout.listener.OnLoadMoreListener;
import com.scwang.smart.refresh.layout.listener.OnRefreshListener;
import java.util.ArrayList;
import java.util.List;
public class MessageFragment extends Fragment {
RecyclerView recyclerView;
List<Chat> chatList = new ArrayList<>();
MyAdapter myAdapter;
SmartRefreshLayout smartRefreshLayout;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_message, container, false);
return view;
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
recyclerView = getActivity().findViewById(R.id.recyclerview);
// 無下拉功能
// 上拉重繪,資料到底 重新加載新資料
// 開源
for (int i = 0; i < 10; i++) {
Chat chat = new Chat();
chat.setTime("下午4:00");
chat.setContent("content" + i);
chat.setName("name" + i);
chat.setImg(R.drawable.a1);
chatList.add(chat);
}
myAdapter = new MyAdapter();
recyclerView.setAdapter(myAdapter);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
smartRefreshLayout=getActivity().findViewById(R.id.SmartRefreshLayout);
smartRefreshLayout.setRefreshHeader(new ClassicsHeader(getActivity()));
smartRefreshLayout.setRefreshFooter(new ClassicsFooter(getActivity()));
smartRefreshLayout.setOnRefreshListener(new OnRefreshListener() {
@Override
public void onRefresh(RefreshLayout refreshlayout) {
// todo 清除資料
chatList.clear();
refreshlayout.finishRefresh(2000/*,false*/);//傳入false表示重繪失敗
for (int i = 0; i < 10; i++) {
Chat chat = new Chat();
chat.setTime("下午4:00 new");
chat.setContent("content new" + i);
chat.setName("name new" + i);
chat.setImg(R.drawable.a1);
chatList.add(chat);
}
myAdapter.notifyDataSetChanged();
}
});
smartRefreshLayout.setOnLoadMoreListener(new OnLoadMoreListener() {
@Override
public void onLoadMore(RefreshLayout refreshlayout) {
// todo 添加資料
// 重新添加資料
for (int i = 10; i < 20; i++) {
Chat chat = new Chat();
chat.setTime("下午4:00");
chat.setContent("content" + i);
chat.setName("name" + i);
chat.setImg(R.drawable.a1);
chatList.add(chat);
}
refreshlayout.finishLoadMore(2000/*,false*/);//傳入false表示加載失敗
myAdapter.notifyDataSetChanged();
}
});
}
public class MyAdapter extends RecyclerView.Adapter<MyViewHolder> {
@NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(getActivity()).inflate(R.layout.item_chat, parent, false);
MyViewHolder myViewHolder = new MyViewHolder(view);
return myViewHolder;
}
@Override
public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
holder.nameTv.setText(chatList.get(position).getName());
holder.contentTv.setText(chatList.get(position).getContent());
holder.timeTv.setText(chatList.get(position).getTime());
holder.imageView.setImageResource(chatList.get(position).getImg());
// getActivity 如果當前類繼承了Activity,就用當前類.this
//Glide.with(getActivity()).load("https://p3.ssl.qhimgs1.com/sdr/400__/t0188e5449327de5e33.jpg").into(holder.imageView);
}
@Override
public int getItemCount() {
return chatList.size();
}
}
public class MyViewHolder extends RecyclerView.ViewHolder {
TextView nameTv;
TextView contentTv;
TextView timeTv;
ImageView imageView;
public MyViewHolder(@NonNull View itemView) {
super(itemView);
nameTv = itemView.findViewById(R.id.nametextview);
contentTv = itemView.findViewById(R.id.contenttextview);
timeTv = itemView.findViewById(R.id.timetextview);
imageView = itemView.findViewById(R.id.imageView);
}
}
}
效果圖

轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/280227.html
標籤:其他
上一篇:位元組序的大端序小端序的判斷方法
下一篇:解決執行緒同步的方案匯總總結
