Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> Android開發 >> 關於android開發 >> Android 大雜燴工程之ListView的開發2以及數據倉庫開發模式

Android 大雜燴工程之ListView的開發2以及數據倉庫開發模式

編輯:關於android開發

Android 大雜燴工程之ListView的開發2以及數據倉庫開發模式


今天是放完假後工作的第一天,為了證明我不是一段幽靈代碼,我給各位看客老爺們說句:祝大家節日過得愉快(過得不愉快那也是人之常情)。

我們繼續來講一講ListView的開發,上次講到了ListView的適配器和布局模式,今天要講的就是簡單卻也適用的點擊事件處理了。之前我們的界面一進去就是跟機器人對話,面向的對象始終只有機器人一個,這次我們來仿照QQ的消息界面那樣有一個對象列表,點擊其中一個就能進入相應的聊天界面。話不多說,先上代碼:

新增一個布局文件activity_chatlist.xml

 

<!--{cke_protected}{C}%3C!%2D%2D%3Fxml%20version%3D%221.0%22%20encoding%3D%22utf-8%22%3F%2D%2D%3E-->
<linearlayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal">

    <imageview android:id="@+id/iv_chatList_icon" android:layout_width="40dp" android:layout_height="40dp" android:layout_marginleft="@dimen/activity_vertical_margin">

    <textview android:id="@+id/tv_chatList_account" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_marginleft="@dimen/activity_vertical_margin" android:gravity="center" android:textsize="@dimen/mid_text_size">
</textview></imageview></linearlayout>
新增兩個java文件ChatActivity.java

 

 

package com.teachmodel.fragment;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;

import com.teachmodel.R;
import com.teachmodel.adapter.ChatAdapter;
import com.teachmodel.bean.Chat;

import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;

/**
 * Created by windbreaker on 16/4/5.
 */
public class ChatActivity extends Activity {

    private ListView mListView;
    private List mList;
    private ChatAdapter mChatAdapter;
    private Hashtable ansChats;
    private EditText et_chat;
    private Button btn_chat;
    private String chatName;
    private int chatIcon;


    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.fragment_first);
        init();
    }

    private void init() {
        Intent intent = getIntent();
        chatName = intent.getStringExtra("account");
        chatIcon = intent.getIntExtra("icon", 0);
        et_chat = (EditText) findViewById(R.id.et);
        btn_chat = (Button) findViewById(R.id.btn);
        mListView = (ListView) findViewById(R.id.lv_chat_list);
        mList = new ArrayList<>();
        ansChats = new Hashtable<>();
        ansChats.put("Hi", "Hello");
        ansChats.put("What is your name?", "My name is DuBe.");
        ansChats.put("What?DouBi?", "Yeah....");
        ansChats.put("Ha...,How interesting", "Thank you.");
        mChatAdapter = new ChatAdapter(mList, this);
        mListView.setAdapter(mChatAdapter);
        btn_chat.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Chat mChat = new Chat();
                mChat.setName("白馬秋風");
                mChat.setIcon(R.mipmap.my);
                mChat.setMessage(et_chat.getText().toString());
                mChatAdapter.addItem(mChat);
                getAns(et_chat.getText().toString());
                et_chat.setText("");
            }
        });
    }

    private void getAns(String question) {
        Chat mChat = new Chat();
        mChat.setName(chatName);
        mChat.setIcon(chatIcon);
        if (ansChats.get(question) != null) {
            mChat.setMessage(ansChats.get(question));
        } else {
            mChat.setMessage("I dont know what you ask?");
        }
        mChatAdapter.addItem(mChat);
        mListView.setSelection(mListView.getBottom());
    }

}

ChatListAdapter.java

 

 

package com.teachmodel.adapter;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;

import com.teachmodel.R;
import com.teachmodel.bean.Chat;

import java.util.List;

/**
 * Created by windbreaker on 16/4/5.
 */
public class ChatListAdapter extends BaseAdapter {
    private List chatList;
    private LayoutInflater mLayoutInflater;

    public ChatListAdapter(List chatList, Context context) {
        this.chatList = chatList;
        this.mLayoutInflater = LayoutInflater.from(context);
    }

    @Override
    public int getCount() {
        return chatList.size();
    }

    @Override
    public Object getItem(int position) {
        return chatList.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder mViewHolder;
        if (convertView == null) {
            convertView = mLayoutInflater.inflate(R.layout.item_chatlist, null);
            mViewHolder = new ViewHolder();
            mViewHolder.iv = (ImageView) convertView.findViewById(R.id.iv_chatList_icon);
            mViewHolder.tv = (TextView) convertView.findViewById(R.id.tv_chatList_account);
            convertView.setTag(mViewHolder);
        } else {
            mViewHolder = (ViewHolder) convertView.getTag();
        }
        mViewHolder.tv.setText(chatList.get(position).getName());
        mViewHolder.iv.setImageResource(chatList.get(position).getIcon());
        return convertView;
    }

    class ViewHolder {
        ImageView iv;
        TextView tv;
    }
}

再改一下FirstFragment.java
package com.teachmodel.fragment;

import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ListView;

import com.teachmodel.R;
import com.teachmodel.adapter.ChatListAdapter;
import com.teachmodel.bean.Chat;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by windbreaker on 16/3/23.
 */
public class FirstFragment extends Fragment {
    private View v;

    private ListView lv;
    private List mList;
    private int[] iconLab = {R.mipmap.ic_launcher, R.mipmap.usericon, R.mipmap.my};
    private String[] nameLab = {"機器人", "管理員", "夜的風衣"};


    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle
            savedInstanceState) {
        v = inflater.inflate(R.layout.activity_chatlist, null);
        init();
        initData();
        return v;
    }

    private void init() {
        lv = (ListView) v.findViewById(R.id.lv_chatList);
        lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView parent, View view, int position, long id) {
                Intent intent = new Intent(getActivity(), ChatActivity.class);
                intent.putExtra("account", mList.get(position).getName());
                intent.putExtra("icon", mList.get(position).getIcon());
                startActivity(intent);
            }
        });
    }

    private void initData() {
        mList = new ArrayList<>();
        for (int i = 0; i < 3; i++) {
            Chat mChat = new Chat();
            mChat.setName(nameLab[i]);
            mChat.setIcon(iconLab[i]);
            mList.add(mChat);
        }
        ChatListAdapter mChatListAdapter = new ChatListAdapter(mList, getActivity());
        lv.setAdapter(mChatListAdapter);
    }

}

記得在AndroidManifest.xml注冊新的activity組件:

至此咋們運行一下,看看效果如何,請看大屏幕:

\\

嗯哼,這略略一看,效果還不錯。咋們來分析分析一下代碼吧,首先是補充說一下上次沒有說的適配器裡的getView()這個方法。

public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder mViewHolder;
if (convertView == null) {
convertView = mLayoutInflater.inflate(R.layout.item_chatlist, null);
mViewHolder = new ViewHolder();
mViewHolder.iv = (ImageView) convertView.findViewById(R.id.iv_chatList_icon);
mViewHolder.tv = (TextView) convertView.findViewById(R.id.tv_chatList_account);
convertView.setTag(mViewHolder);
} else {
mViewHolder = (ViewHolder) convertView.getTag();
}
mViewHolder.tv.setText(chatList.get(position).getName());
mViewHolder.iv.setImageResource(chatList.get(position).getIcon());
return convertView;
}

第一行代碼我們就看到了這個ViewHolder內部類,這個類是用來干什麼的呢?這個其實是對布局文件item_chatlist裡的控件的一個抽象,這個類裡有有一個ImageView和TextView 剛好對應於布局文件裡的兩個控件。接下來的代碼則是檢查是否已經存在View對象了,如果沒有則重新實例化,有的話就直接使用了。這樣說起來可能比較抽象。咋們打個比方:把程序比較教官,把要實例化的對象看成是一排要報名的隊員。現在教官知道一共有多少人,但是不知道有多少人已經發了身份卡(ViewHolder)。所以他開始點名,也就是這個過程:

if (convertView == null) {
convertView = mLayoutInflater.inflate(R.layout.item_chatlist, null);
mViewHolder = new ViewHolder();
mViewHolder.iv = (ImageView) convertView.findViewById(R.id.iv_chatList_icon);
mViewHolder.tv = (TextView) convertView.findViewById(R.id.tv_chatList_account);
convertView.setTag(mViewHolder);
} else {
mViewHolder = (ViewHolder) convertView.getTag();
}

先判斷你有沒有身份卡,沒有的話我發給你一張

mViewHolder = new ViewHolder();
mViewHolder.iv = (ImageView) convertView.findViewById(R.id.iv_chatList_icon);
mViewHolder.tv = (TextView) convertView.findViewById(R.id.tv_chatList_account);

這個身份卡就是我以後找你你的標志了convertView.setTag(mViewHolder);

你拿了之後,把姓名和頭像給寫上

mViewHolder.tv.setText(chatList.get(position).getName());
mViewHolder.iv.setImageResource(chatList.get(position).getIcon());

如果你有的話,教官根據標簽要求你拿出你相應的身份卡我看看

mViewHolder = (ViewHolder) convertView.getTag();

然後再給你核對一下你的身份卡信息

mViewHolder.tv.setText(chatList.get(position).getName());
mViewHolder.iv.setImageResource(chatList.get(position).getIcon());

直到把所有的隊友的檢查完一遍沒問題就OK了。

講完適配器的工作原理,咋們再來講講ListView如何響應點擊事件。

listView的點擊事件是很簡單的,只需要在實例化後(lv = (ListView) v.findViewById(R.id.lv_chatList);)使用這個方法

lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterViewparent, View view, int position, long id) {
//你的執行代碼

Intent intent = new Intent(getActivity(), ChatActivity.class);
intent.putExtra("account", mList.get(position).getName());
intent.putExtra("icon", mList.get(position).getIcon());
startActivity(intent);
}
});
就可以處理點擊事件了。這裡的position就是你點擊的列表的第幾項。

就這樣,ListView的講解就先到這裡。我們接下來講講數據倉庫的設計模式。

再講這個概念之前,我們先來講講我們的程序,如你所見的,我們程序裡的所有數據都是在activity裡生成的,也就是說activity不僅僅要定義變量,管理變量,獲取控件,處理控件的監聽事件還要生成並且處理數據,管理跳轉邏輯,管理自身的生命周期等等。如果讓一個人來處理這些事情,我想那個人即使不會跳樓,也會不勝其煩。同樣,這樣對於activity來說也是不好的,因為他管理的東西太多太雜了。那咋辦呢?難道也要上天嗎?與太陽肩並肩?對於這個問題,我們只要做一下職能分離就好,就是把數據生成和數據處理的功能單獨出來,activity只負責獲取數據集合就OK了,這就是所謂的數據倉庫設計了。不瞎逼逼,咋們來看看具體實現。

新增一個java文件:ChatLab.java

 

package com.teachmodel.bean;

import com.teachmodel.R;

import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;

/**
 * Created by windbreaker on 16/4/5.
 */
public class ChatLab {

    private static ChatLab mChatLab;
    private static List mList;
    private Hashtable ansChats;
    private int[] iconLab = {R.mipmap.ic_launcher, R.mipmap.usericon, R.mipmap.my};
    private String[] nameLab = {"機器人", "管理員", "夜的風衣"};

    private ChatLab() {

        mList = new ArrayList<>();
        for (int i = 0; i < 3; i++) {
            Chat mChat = new Chat();
            mChat.setName(nameLab[i]);
            mChat.setIcon(iconLab[i]);
            mList.add(mChat);
        }

        ansChats = new Hashtable<>();
        ansChats.put("Hi", "Hello");
        ansChats.put("What is your name?", "My name is DuBe.");
        ansChats.put("What?DouBi?", "Yeah....");
        ansChats.put("Ha...,How interesting", "Thank you.");
    }

    public static ChatLab getInstance() {
        if (mChatLab == null) {
            mChatLab = new ChatLab();
        }
        return mChatLab;
    }

    public List getList() {
        return mList;
    }

    public Hashtable getAns() {
        return ansChats;
    }
}

然後修改一下FirstFragment.java和ChatActivity.java

 

 

package com.teachmodel.fragment;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;

import com.teachmodel.R;
import com.teachmodel.adapter.ChatAdapter;
import com.teachmodel.bean.Chat;
import com.teachmodel.bean.ChatLab;

import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;

/**
 * Created by windbreaker on 16/4/5.
 */
public class ChatActivity extends Activity {

    private ListView mListView;
    private List mList;
    private ChatAdapter mChatAdapter;
    private EditText et_chat;
    private Button btn_chat;
    private String chatName;
    private int chatIcon;
    private Hashtable ansChats;


    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.fragment_first);
        init();
        initData();
    }

    private void init() {
        et_chat = (EditText) findViewById(R.id.et);
        btn_chat = (Button) findViewById(R.id.btn);
        mListView = (ListView) findViewById(R.id.lv_chat_list);
    }

    private void initData() {
        Intent intent = getIntent();
        chatName = intent.getStringExtra("account");
        chatIcon = intent.getIntExtra("icon", 0);
        ansChats = ChatLab.getInstance().getAns();
        mList = new ArrayList<>();

        mChatAdapter = new ChatAdapter(mList, this);
        mListView.setAdapter(mChatAdapter);
        btn_chat.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Chat mChat = new Chat();
                mChat.setName("白馬秋風");
                mChat.setIcon(R.mipmap.my);
                mChat.setMessage(et_chat.getText().toString());
                mChatAdapter.addItem(mChat);
                getAns(et_chat.getText().toString());
                et_chat.setText("");
            }
        });
    }

    private void getAns(String question) {
        Chat mChat = new Chat();
        mChat.setName(chatName);
        mChat.setIcon(chatIcon);
        if (ansChats.get(question) != null) {
            mChat.setMessage(ansChats.get(question));
        } else {
            mChat.setMessage("I dont know what you ask?");
        }
        mChatAdapter.addItem(mChat);
        mListView.setSelection(mListView.getBottom());
    }

}

package com.teachmodel.fragment;

import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ListView;

import com.teachmodel.R;
import com.teachmodel.adapter.ChatListAdapter;
import com.teachmodel.bean.Chat;
import com.teachmodel.bean.ChatLab;

import java.util.List;

/**
 * Created by windbreaker on 16/3/23.
 */
public class FirstFragment extends Fragment {
    private View v;

    private ListView lv;
    private List mList;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle
            savedInstanceState) {
        v = inflater.inflate(R.layout.activity_chatlist, null);
        init();
        initData();
        return v;
    }

    private void init() {
        lv = (ListView) v.findViewById(R.id.lv_chatList);
        lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView parent, View view, int position, long id) {
                Intent intent = new Intent(getActivity(), ChatActivity.class);
                intent.putExtra("account", mList.get(position).getName());
                intent.putExtra("icon", mList.get(position).getIcon());
                startActivity(intent);
            }
        });
    }

    private void initData() {
        mList = ChatLab.getInstance().getList();
        ChatListAdapter mChatListAdapter = new ChatListAdapter(mList, getActivity());
        lv.setAdapter(mChatListAdapter);
    }

}

運行一下即可得出上圖的結果。然後有的人也許會問這種設計模式有什麼用?難道能提高程序的運行效率?這個也許沒有提高程序的運行效率,反而還有可能略略影響了你的程序運行效率。說到這裡,你也許會說我是個坑比。對此,我只能說,為什麼會有這種設計模式呢?其實程序的所有設計模式都是以方便管理和編程為目的的,對於運行效率的提高主要是與你編程的算法有關。對於之前的無模式編程,如果你只有幾行代碼,其實有沒有設計模式都無所謂了。但是你有幾千甚至上萬行代碼的話,設計模式的就顯得尤其重要。以數據倉庫為例,如果你的程序有很多地方都要用到相同的數據,每個地方都要生成並且初始化數據,那不如把數據和調用數據的方法集中在一起,要用的數據的地方直接調用數據倉庫裡的數據就行了,自己也不用去管理數據了。這樣是十分有利於整理思路和修改代碼的。

今天就說到這裡了,感謝各位看客老爺們的圍觀。

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved