Android進階:網路與資料儲存—步驟1:Android網路與通訊(第4小節:ListView下)
阿新 • • 發佈:2018-12-13
內容概括:
一、網路下載資料並顯示在ListView上
- 使用非同步訪問網路
- 解析獲取的Json資料
- 載入資料到ListView上
二、不同item的引用
- 引用不同行佈局
一、網路下載資料並顯示在ListView上
1.1-使用非同步訪問網路
//非同步訪問網路 public class RquestDataAsyncTask extends AsyncTask<Void, Void, String> { //請求開始之前 @Override protected void onPreExecute() { super.onPreExecute(); //loading } @Override protected String doInBackground(Void... voids) {//子執行緒耗時操作 } @Override protected void onPostExecute(String s) { super.onPostExecute(s); //loading 消失,資料處理,重新整理介面 } }
在AndroidManifest.xml中新增訪問網路許可權:
<uses-permission android:name="android.permission.INTERNET"/>
在doInbackground中進行網路訪問
@Override protected String doInBackground(Void... voids) {//子執行緒耗時操作 return request("http://www.imooc.com/api/teacher?type=2&page=1");//呼叫request } //返回獲取到的String內容 private String request(String urlString) { try { URL url = new URL(urlString); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setConnectTimeout(300000); connection.setRequestMethod("GET"); connection.connect(); int responseCode = connection.getResponseCode(); if (responseCode == HttpURLConnection.HTTP_OK) {//如果訪問成功 InputStreamReader inputStreamReader = new InputStreamReader(connection.getInputStream()); //包裝類,它可以包裝字元輸入流,將字元流放入快取裡,先把字元讀到快取裡 // 到快取滿了或者你flush的時候,再讀入記憶體,就是為了提供讀的效率而設計的 BufferedReader bufferedReader = new BufferedReader(inputStreamReader); StringBuilder stringBuilder = new StringBuilder(); String line; //每次讀一行,直到它為空,並把當前這一個的資料賦值給line while ((line = bufferedReader.readLine()) != null) { stringBuilder.append(line); } return stringBuilder.toString();//返回拼接的資料 } } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return null;//如果訪問失敗返回null }
1.2-解析獲取的Json資料
拿到資料後要將資料做成一個物件,展示出來(解析)
執行將上面拿到的資料進行轉化成物件:
1-建立一個封裝json資料的類LessonResult.java
/** * 這個類封裝整個json物件的屬性 */ public class LessonResult { //跟json的格式一致 private String mMessage; private int mStatus; private List<LessonInfo> mLessonInfoList=new ArrayList<>();//裝每個數組裡面的內容 public String getmMessage() { return mMessage; } public void setmMessage(String mMessage) { this.mMessage = mMessage; } public int getmStatus() { return mStatus; } public void setmStatus(int mStatus) { this.mStatus = mStatus; } public List<LessonInfo> getmLessonInfoList() { return mLessonInfoList; } public void setmLessonInfoList(List<LessonInfo> mLessonInfoList) { this.mLessonInfoList = mLessonInfoList; } }
這個 LessonInfo封裝的是data數組裡面的屬性
/**
* 這個類封裝陣列data裡面每一個物件的屬性
*/
public class LessonInfo {
String mName;
String mDescription;
//僅拿了2個屬性
public String getmName() {
return mName;
}
public void setmName(String mName) {
this.mName = mName;
}
public String getmDescription() {
return mDescription;
}
public void setmDescription(String mDescription) {
this.mDescription = mDescription;
}
}
3-在onPostExecute中進行UI更新,將拿到的資料進行資料轉換(封裝顯示)
//將執行後返回的結果(就是拼接的資料)進行處理
/**
* 執行資料轉換功能
* @param result
*/
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
//loading 消失,資料處理,重新整理介面
LessonResult lessonResult=new LessonResult();
try {
//得到的json資料的物件
JSONObject jsonObject=new JSONObject(result);
//為lessonResult裡面的Status賦值
//status:1 表示是int型的;“ ”表示是字串型的;true or false表示是boolean型別的
lessonResult.setmStatus(jsonObject.getInt("status"));
//拿到json資料裡面的message
lessonResult.setmMessage(jsonObject.getString("msg"));
//用這個List裝數組裡面的資料
List<LessonInfo> lessonInfos=new ArrayList<>();
//拿到陣列data裡面的資料
JSONArray dataArray=jsonObject.getJSONArray("data");
for(int index=0;index<dataArray.length();index++){
//給lessonInfo賦值
LessonInfo lessonInfo=new LessonInfo();
//陣列data裡面又有10個物件{},所以要先把每一個物件拿出來
JSONObject tempJsonObject= (JSONObject) dataArray.get(index);
//給lessonInfo裡的name賦值
lessonInfo.setmName( tempJsonObject.getString("name"));
lessonInfos.add(lessonInfo);
}
//迴圈結束lessonResult賦值
lessonResult.setmLessonInfoList(lessonInfos);
} catch (JSONException e) {
e.printStackTrace();
}
}
1-3載入資料到ListView上
新建一個Adapter類繼承baseAdapter
public class RequestDataAdapter extends BaseAdapter {
private List<LessonInfo> mLessonInfos;//定義一個全域性變數,在構造器中獲取初始值
Context mcontext;
//帶參構造,將List<LessonInfo>資料傳進來,只要顯示資料的資料
public RequestDataAdapter(Context context, List<LessonInfo> infos) {
this.mLessonInfos = infos;
this.mcontext = context;
}
@Override
public int getCount() {
return mLessonInfos.size();
}
@Override
public Object getItem(int position) {
return mLessonInfos.get(position);
}
@Override
public long getItemId(int position) {
//可以獲取它的資料裡面的屬性返回
// return mLessonInfos.get(position).getmName();
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder = new ViewHolder();
//需要Context才有getSystem的方法
//實現快取優化
if (convertView == null) {
LayoutInflater layoutInflater = (LayoutInflater) mcontext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = layoutInflater.inflate(R.layout.item_app_list, null);
viewHolder.appNameTextView = convertView.findViewById(R.id.app_name_text_view);
viewHolder.appIconImageView = convertView.findViewById(R.id.app_icom_image_view);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
//將這個資料裡面的Name顯示到ListViewItem上每一個TextView
}
viewHolder.appNameTextView.setText(mLessonInfos.get(position).getmName());
viewHolder.appIconImageView.setVisibility(View.GONE);//讓這個元件消失
return convertView;
}
public class ViewHolder {
public TextView appNameTextView;
public ImageView appIconImageView;
}
}
在onPostExecute方法後,繫結介面卡
//listView繫結介面卡(資料)
listView.setAdapter(new RequestDataAdapter(RequestDataActivity.this,lessonResult.getmLessonInfoList()));
在初始化時執行AsyncTask
//執行AsyncTask
new RquestDataAsyncTask().execute();
完成。
convertView=LayoutInflater.from(mcontext).inflate(R.layout.item_app_list,null);
上面這一行,可以替換下面這種寫法:
LayoutInflater layoutInflater = (LayoutInflater) mcontext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = layoutInflater.inflate(R.layout.item_app_list, null);
二、不同item的引用
/** * 做一個模仿聊天介面的ListView * 首先,建立檢視 * 然後,設定資料 * 最後,繫結介面卡顯示 */
主介面ChatActivity.java
public class ChatActivity extends AppCompatActivity {
private ListView listView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chat);
//1建立檢視 和兩個item佈局
listView = findViewById(R.id.chat_list_view);
//2設定資料
//新建一個動態陣列裝資料
ArrayList<Chat_Data> arrayList=new ArrayList<>();
arrayList.add(new Chat_Data(
1,2,
"我","8:58",
"在嗎",false));
arrayList.add(new Chat_Data(
1,2,
"小米","8:59",
"在",true));
arrayList.add(new Chat_Data(
1,2,
"我","8:59",
"天氣怎麼樣",false));
arrayList.add(new Chat_Data(
1,2,
"小米","9:00",
"熱成狗了",true));
arrayList.add(new Chat_Data(
1,2,
"小米","9:00",
"哇哇哇",true));
//設定介面卡
listView.setAdapter(new ChatAdapter(arrayList,ChatActivity.this));
}
設定資料封裝:Chat_Data.java
public class Chat_Data {
private int mID;
private int mFriendID;
private String mName;
private String mDate;
private String mContent;
boolean mIsComMessage;
//構造方法賦值
public Chat_Data(int mID, int mFriendID, String mName,String mDate, String mContent, boolean mIsComMessage) {
this.mID = mID;
this.mFriendID = mFriendID;
this.mName = mName;
this.mDate=mDate;
this.mContent = mContent;
this.mIsComMessage = mIsComMessage;
}
public String getmDate() {
return mDate;
}
public void setmDate(String mDate) {
this.mDate = mDate;
}
public int getmID() {
return mID;
}
public void setmID(int mID) {
this.mID = mID;
}
public int getmFriendID() {
return mFriendID;
}
public void setmFriendID(int mFriendID) {
this.mFriendID = mFriendID;
}
public String getmName() {
return mName;
}
public void setmName(String mName) {
this.mName = mName;
}
public String getmContent() {
return mContent;
}
public void setmContent(String mContent) {
this.mContent = mContent;
}
public boolean ismIsComMessage() {
return mIsComMessage;
}
public void setmIsComMessage(boolean mIsComMessage) {
this.mIsComMessage = mIsComMessage;
}
}
設定介面卡ChatAdapter.java
public class ChatAdapter extends BaseAdapter {
ArrayList<Chat_Data> mChat_Data = new ArrayList<>();
Context mContext;
//定義一個介面實現判斷是哪個檢視
interface MessageViewType {
int COM_MESSAGE = 0;
int TO_MESSAGE = 1;
}
public ChatAdapter(ArrayList<Chat_Data> mArrayList, Context mContext) {
this.mChat_Data = mArrayList;
this.mContext = mContext;
}
@Override
public int getCount() {
return mChat_Data.size();
}
@Override
public Object getItem(int position) {
return mChat_Data.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public int getItemViewType(int position) {
Chat_Data chat_data = mChat_Data.get(position);
//拿到訊息型別
boolean MSG = chat_data.ismIsComMessage();
//返回訊息型別
return MSG ? MessageViewType.COM_MESSAGE : MessageViewType.TO_MESSAGE;
}
//有2種顯示型別的檢視
@Override
public int getViewTypeCount() {
return 2;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
Chat_Data chat_data = mChat_Data.get(position);
boolean IsComMsg = chat_data.ismIsComMessage();
ViewHolder viewHolder = new ViewHolder();
if (convertView == null) {
if (chat_data.ismIsComMessage()) {//如果是來的訊息
convertView = LayoutInflater.from(mContext).inflate(R.layout.chat_left_item, null);
} else {//
convertView = LayoutInflater.from(mContext).inflate(R.layout.chat_right_item, null);
}
viewHolder.mIcon = convertView.findViewById(R.id.iv_user_head);
viewHolder.mName = convertView.findViewById(R.id.tv_username);
viewHolder.mContent = convertView.findViewById(R.id.tv_chat_content);
viewHolder.mDate = convertView.findViewById(R.id.tv_send_time);
viewHolder.mContent.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
viewHolder.IsComMsg = IsComMsg;
convertView.setTag(viewHolder);
} else
viewHolder = (ViewHolder) convertView.getTag();
viewHolder.mName.setText(chat_data.getmDate());
viewHolder.mDate.setText(chat_data.getmDate());
viewHolder.mContent.setText(chat_data.getmContent());
if (IsComMsg) {
viewHolder.mIcon.setImageResource(R.mipmap.ic_launcher);
} else {
viewHolder.mIcon.setImageResource(R.mipmap.ic_launcher_round);
}
return convertView;
}
public class ViewHolder {
public TextView mContent, mName, mDate;
public ImageView mIcon;
public boolean IsComMsg;
}
}
佈局左:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="6dp">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:orientation="vertical">
<TextView
android:id="@+id/tv_send_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="2dp"
android:text="18:20"
android:textColor="#CCCCCC" />
</LinearLayout>
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_marginTop="5dp">
<ImageView
android:id="@+id/iv_user_head"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:background="@mipmap/ic_launcher"
android:clickable="true" />
<TextView
android:id="@+id/tv_chat_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_toRightOf="@id/iv_user_head"
android:background="#ffff"
android:gravity="left|center"
android:lineSpacingExtra="2dp"
android:minHeight="36dp"
android:minWidth="50dp"
android:text="@string/app_name"
android:textColor="#494949"
android:textSize="18sp" />
<TextView
android:id="@+id/tv_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="10dp"
android:layout_toRightOf="@id/tv_chat_content"
android:clickable="true"
android:focusable="true"
android:gravity="left|center"
android:lineSpacingExtra="2dp"
android:minHeight="50dp"
android:textColor="#ff000000"
android:textSize="15sp" />
<TextView
android:id="@+id/tv_username"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="@id/iv_user_head"
android:layout_toLeftOf="@id/tv_chat_content"
android:gravity="center"
android:singleLine="true"
android:text=""
android:textColor="#818181"
android:textSize="14sp"
android:visibility="visible" />
</RelativeLayout>
佈局右:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="6dp" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="center_horizontal">
<TextView
android:id="@+id/tv_send_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="2dp"
android:textColor="#ffffff"
android:textSize="12sp"
android:background="#bfbfbf"/>
</LinearLayout>
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:layout_marginRight="5dp" >
<ImageView
android:id="@+id/iv_user_head"
android:layout_width="40dp"
android:layout_height="40dp"
android:focusable="false"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:background="@mipmap/ic_launcher"/>
<TextView
android:id="@+id/tv_chat_content"
android:layout_toLeftOf="@id/iv_user_head"
android:layout_marginRight="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minWidth="50dp"
android:textColor="#000"
android:background="#fff"
android:textSize="15sp"
android:gravity="left|center"
android:minHeight="40dp"
android:lineSpacingExtra="2dp"
android:clickable="true"
android:focusable="true"/>
<TextView
android:id="@+id/tv_time"
android:layout_toLeftOf="@id/tv_chat_content"
android:layout_marginRight="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="15sp"
android:textColor="#ff000000"
android:gravity="left|center"
android:minHeight="50dp"
android:lineSpacingExtra="2dp"
android:clickable="true"
android:focusable="true"/>
<TextView
android:id="@+id/tv_username"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/iv_user_head"
android:layout_alignParentRight="true"
android:layout_toRightOf="@id/tv_chat_content"
android:textSize="15sp"
android:gravity="center"
android:textColor="#818181"/>
</RelativeLayout>
</LinearLayout>