Android 整合okhttp3、listview解析json資料
上上篇文章寫了個Android的模擬介面,終於派上用場了
現在我們將接口裡面的json資料通過ListView顯示出來,效果如下:
先講一下ListView吧, 講ListView之前,肯定要講Adapter,在Android應用程式中,採用資料和顯示分開實現的資料處理方式,由於資料來源形式多樣,例如ListView所展示的資料格式是有一定要求的,為匹配這個變換,,中間加了介面卡。資料介面卡正是建立了資料來源與ListView之間的適配關係,將資料來源轉換為ListView能夠顯示的資料格式,從而將資料的來源 與資料的顯示進行 解耦,降低程式的耦合度。我這次用的是最常用的BaseAdapter,直接放程式碼,註釋都在程式碼裡。
public class MyAdapter extends BaseAdapter { private LinkedList<ClientInfo> mData;//ClientInfo為資料來源的內容格式 private Context context;//佈局裝載器物件 public MyAdapter(LinkedList<ClientInfo> mData, Context context) { this.mData = mData; this.context = context; } //要繫結的條目的數目 @Override public int getCount() { return mData.size(); } //根據一個索引(位置)獲取該位置的物件 @Override public Object getItem(int position) { return mData.get(position); } //獲取條目的id @Override public long getItemId(int position) { return position; } //獲取該條目要顯示的介面 @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder viewHolder; //如果view未被例項化過,快取池中沒有對應的快取 if (convertView==null){ viewHolder = new ViewHolder(); convertView = LayoutInflater.from(context).inflate(R.layout.item_list_client,parent,false); viewHolder.userName = (TextView) convertView.findViewById(R.id.username); viewHolder.name1 = (TextView) convertView.findViewById(R.id.name); viewHolder.phone = (TextView) convertView.findViewById(R.id.phone); viewHolder.address = (TextView) convertView.findViewById(R.id.address); //用setTag將convertView和viewHolder關聯 convertView.setTag(viewHolder); }else { viewHolder = (ViewHolder) convertView.getTag(); } //取出bean物件 ClientInfo clientInfo = mData.get(position); //設定控制元件的資料 viewHolder.userName.setText(clientInfo.getUserName()); viewHolder.name1.setText(clientInfo.getName()); viewHolder.phone.setText(clientInfo.getPhone()); viewHolder.address.setText(clientInfo.getAddress()); return convertView; } //ViewHolder用於快取控制元件, class ViewHolder{ public TextView userName; public TextView name1; public TextView phone; public TextView address; } }
獲取介面中的資料,肯定是需要先 定義一個實體類的,我這裡就不全放程式碼了主要就是定義了幾個變數,建構函式還有一堆set、get方法,變數名貼一下。
public class ClientInfo {
private String userName;
private String name;
private String phone;
private String address;
}
接下來是重頭戲,okhttp3,看這裡
public class Okhttp2Activity extends AppCompatActivity { private Context mContext; private List<ClientInfo> mData=null; private MyAdapter myAdapter = null; private ListView listView; private Button btn; private final String url="http://192.168.43.210:8081/getJson"; private OkHttpClient client; private JSONObject jsonObject1,jsonObject2; private JSONArray jsonArray; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_okhttp2); mContext = Okhttp2Activity.this; listView = (ListView) findViewById(R.id.list_client); btn = (Button) findViewById(R.id.btn); client = new OkHttpClient(); btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Request request = new Request.Builder() .url(url) .cacheControl(CacheControl.FORCE_NETWORK) .build(); //非同步請求 client.newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { Toast.makeText(Okhttp2Activity.this,e.getMessage(),Toast.LENGTH_SHORT).show(); } @Override public void onResponse(Call call, Response response) throws IOException { final String responseString = response.body().string(); //在主執行緒中修改UI runOnUiThread(new Runnable() { @Override public void run() { try { jsonObject1 = new JSONObject(responseString); jsonArray = jsonObject1.optJSONArray("data"); mData = new LinkedList<ClientInfo>(); for(int i = 0;i<jsonArray.length();i++){ jsonObject2 = jsonArray.optJSONObject(i); String username = jsonObject2.getString("client_username"); String name1 = jsonObject2.getString("client_name"); String phone = jsonObject2.getString("client_phone"); String address = jsonObject2.getString("client_address"); ClientInfo clientInfo = new ClientInfo(username,name1,phone,address); mData.add(clientInfo); } myAdapter = new MyAdapter((LinkedList<ClientInfo>) mData,mContext); listView.setAdapter(myAdapter); } catch (JSONException e) { e.printStackTrace(); } } }); } }); } }); } }
資料格式在我的上上篇部落格中有,可以去看一下。
對於ListView其實只需要進行這幾步
(1)在佈局中放置ListView控制元件
(2)準備ListView顯示的資料,我們這裡是 LinkedList<ClientInfo>
(3)獲取佈局的ListView控制元件
listView = (ListView) findViewById(R.id.list_client);
(4)定義並初始化一個介面卡
myAdapter = new MyAdapter((LinkedList<ClientInfo>) mData,mContext);
(5)將前面定義的介面卡,利用ListView的函式setAdapter()設定
listView.setAdapter(myAdapter);
然後講一下OkHttp的具體使用方法
(1)首先建立一個OkHttpClient的例項,程式碼如下
OkHttpClient client = new OkHttpClient();
(2)建立一個request物件,設定好目標地址,這裡發起的是get請求
private final String url="http://192.168.43.210:8081/getJson";
Request request = new Request.Builder() .url(url) .cacheControl(CacheControl.FORCE_NETWORK) .build();
(3)呼叫OkHttpClient的newCall()方法,建立Call物件,並呼叫它的exqueue()方法(非同步請求),建立一個Callback實 例,重寫他的兩個方法。
其中,response物件就是伺服器返回的資料,獲取返回的json資料
final String responseString = response.body().string();
然後就是解析json格式的資料,並放入介面卡繫結的LinkedList<ClientInfo>當中。
當然不要忘了在manifest裡面新增網路許可權<uses-permission android:name="android.permission.INTERNET" />
還有okttp3的架包
dependencies
{
...
compile 'com.squareup.okhttp3:okhttp:3.2.0' compile 'com.squareup.okio:okio:1.7.0'
...
}
最後貼一下兩個簡單的xml檔案
(1)item_list_client.xml
<?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:orientation="horizontal">
<TextView
android:id="@+id/username"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"/>
<TextView
android:id="@+id/name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"/>
<TextView
android:id="@+id/phone"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"/>
<TextView
android:id="@+id/address"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"/>
</LinearLayout>
(2)activity_okhttp2.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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="com.example.administrator.myapplication.Okhttp2Activity"
android:orientation="vertical">
<Button
android:id="@+id/btn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="查詢" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="@+id/username1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="使用者名稱"/>
<TextView
android:id="@+id/name1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="姓名"/>
<TextView
android:id="@+id/phone1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="手機號碼"/>
<TextView
android:id="@+id/address1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="地址"/>
</LinearLayout>
<ListView
android:id="@+id/list_client"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</ListView>
</LinearLayout>