Android RecyclerView瀑布流展示(OkHttp協議)
阿新 • • 發佈:2019-01-07
一言不合就上圖
OkHttp和recyclerView都是第三方提供的,so先注入依賴
//okhttp3網路請求協議
compile 'com.squareup.okhttp3:okhttp:3.9.0'
//recyclerview控制元件
compile 'com.android.support:recyclerview-v7:26.0.0-alpha1'
//Glide圖片載入
compile 'com.github.bumptech.glide:glide:3.7.0'
//Gson Json串解析工具
compile 'com.google.code.gson:gson:2.8.1'
然後是寫MainActicity的主佈局:(注意最外層的佈局,方向orientation要寫成”vertical”,垂直後面會用到)
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v7.widget.RecyclerView
android:id="@+id/recView"
android:layout_width="match_parent"
android:layout_height="match_parent"></android.support.v7.widget.RecyclerView>
</LinearLayout>
和Item的子佈局rec_item:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width ="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ImageView
android:id="@+id/recIv"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:scaleType="fitXY"
android:src="@mipmap/ic_launcher_round" />
<TextView
android:id="@+id/recTv"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="14"
android:gravity="center"
android:singleLine="true"
android:text="這是標題"
android:textSize="22sp"/>
</LinearLayout>
RecyclerView.Adapter介面卡類(此類我抽出來了)程式碼:
public class RecAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
//用來存放子條目高度的集合
private List<Integer> heightList;
//為了配合呼叫此介面卡的類的傳值呼叫,此倆個屬性是傳過來的上下文和集合,做下繫結而已
//也就是有參構造器
private MainActivity context;
private List<LadyBean.NewslistBean> list;
public RecAdapter(MainActivity context, List<LadyBean.NewslistBean> list) {
this.context = context;
this.list = list;
//設定n個隨機數,這裡的隨機數,將設定給ImageView控制元件的高度上賦值
//然後把這些個隨機數放到幾個,integer泛型的集合裡面
heightList = new ArrayList<Integer>();
for (int i = 0; i < list.size(); i++) {
int height = new Random().nextInt(400) + 250;//[250,400)的隨機數
//把隨機數放入集合裡
heightList.add(height);
}
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
//填充佈局或渲染布局
View view = View.inflate(context, R.layout.rec_item, null);
//把渲染好的佈局放入自定義的ViewHolder裡,並return返回
RecViewholder recViewholder = new RecViewholder(view);
return recViewholder;
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
//繫結資料優化並強轉
RecViewHolder recViewHolder = (RecViewHolder) holder;
//獲取ViewGroup的可編輯佈局管理 ,然後給imageView控制元件賦可編輯的權利
ViewGroup.LayoutParams params = recViewHolder.imageView.getLayoutParams();
//然後設定高度從heightList集合裡面拿當前的隨機數,
params.height = heightList.get(position);
//把隨機數賦給imageView這個控制元件
recViewHolder.imageView.setLayoutParams(params);
//繫結給當前位置上的imageView控制元件
holder.itemView.setTag(position);
//給textView文字賦值
recViewHolder.textView.setText(list.get(position).getTitle());
//給圖片賦值
Glide.with(context).load(list.get(position).getPicUrl()).into(recViewHolder.imageView);
}
@Override
public int getItemCount() {
//三元運算子:如果list不等於空返回list的長度:否則返回0
//相當於if判空處理
return list != null ? list.size() : 0;
}
//內部類自定義優化繼承ViewHolder,生成RecViewHolder的方法
class RecViewHolder extends RecyclerView.ViewHolder {
private final ImageView imageView;
private final TextView textView;
public RecViewHolder(View itemView) {
super(itemView);
//這裡的強制轉換,有人的studio不用強轉也不報錯也能出效果,可能是跟API版本有關吧
imageView = (ImageView) itemView.findViewById(R.id.recIv);
textView = (TextView) itemView.findViewById(R.id.recTv);
}
}
}
接下來就是MainActivity的內容了:
public class MainActivity extends AppCompatActivity {
//快捷鍵:Ctrl+Alt+F 生成的全域性變數
private RecyclerView recView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initData();
}
private void initData() {
recView = (RecyclerView) findViewById(R.id.recView);
//設定recyclerView的樣式:“線性佈局管理器”+引數是“當前上下文”
// recView.setLayoutManager(new LinearLayoutManager(this));
//瀑布流
recView.setLayoutManager(new StaggeredGridLayoutManager(2,StaggeredGridLayoutManager.VERTICAL));
//new 出來OkHttp
OkHttpClient ok = new OkHttpClient();
//預設的GET請求方式
Request request = new Request.Builder()
.url("http://api.tianapi.com/meinv/?key=2a0024d1f7f558e09936f697580f1643&num=10")
.build();
Call call = ok.newCall(request);
//用call呼叫enqueue非同步網路請求,
call.enqueue(new Callback() {
//new出來的介面卡,做了全域性,此處是快捷生成的
private RecAdapter recAdapter;
@Override
public void onFailure(Call call, IOException e) {
Toast.makeText(MainActivity.this,"請求失敗,失敗原因"+e,Toast.LENGTH_SHORT).show();
}
@Override
public void onResponse(Call call, Response response) throws IOException {
//此處是請求成功的方法,
//response是請求過來的資料,把它轉成我們能看懂的String型別字串,方便下面的Gson.FromJson用
String json = response.body().string();
Log.e("++++++++++訪問到的結果:", json);
//此處的Gson 就需要注入依賴包了
Gson gson = new Gson();
LadyBean ladyBean = gson.fromJson(json, LadyBean.class);
//拿到bean裡面的集合
List<LadyBean.NewslistBean> list = ladyBean.getNewslist();
Log.e("+++++集合裡面的東西是:", list + "");
//new 出來你的介面卡,傳一個上下文和集合
recAdapter = new RecAdapter(MainActivity.this, list);
//開啟返回主執行緒的執行緒,並且更新主UI,
// 因為OKHttp預設在子執行緒請求資料,子執行緒不能更新UI,(會報錯或者無法顯示資料)
//所以要手動開啟返回主執行緒的方法,並更新UI檢視
//假如你是Fragment裡面,就要用:上下文再打點呼叫runOnUiThread()方法,否則打點調出不來
runOnUiThread(new Runnable() {
@Override
public void run() {
//設定介面卡
recView.setAdapter(recAdapter);
}
});
}
});
}
}
這就OK了
強調幾點:
1我的Android studio是2.3.3版本,SDK用的v7…..26.+的
2為了顯得程式碼簡潔,導包我沒搬過來,so 你們自己導吧
3如果訪問網路:別忘記在AndroidManifest(註冊清單)新增網路許可權
<uses-permission android:name="android.permission.INTERNET" />