Android快速開發之——最常用的基本列表框架搭建
阿新 • • 發佈:2019-02-06
框架基本介紹:
這是一個基本的列表頁面的開發框架,這個列表頁面的功能有:可自由配置標題欄、下拉重新整理、上拉載入、網路請求時展示等待動畫、請求失敗及資料為空的頁面展示。
寫在前面:
本文可以自由的進行網路請求框架、圖片載入框架、上拉重新整理下拉載入框架、載入等待動效框架的自由配置。配置鴻洋大神的萬能的ListView的介面卡框架。
這樣一個完整功能的列表頁面,你們需要多少程式碼?
private List<BeanMyTask> datas;
private CommeAdapter<BeanMyTask> adapter;
@Override
protected UsingListBySon initDataBySon() {
return new UsingListBySon(){
@Override
public void parseJsonMessage(String msg) {
try {
loadingSwitch(false);
refershSwitch(true);
refershSwitch(false );
Gson gson = new Gson();
BeanMyTaskNet beanMyTaskNet = gson.fromJson(msg , BeanMyTaskNet.class);
if (!beanMyTaskNet.isSuccess()){
OkToast.getInstance(beanMyTaskNet.getMsg());
}else {
int counts = beanMyTaskNet.getBody().getDatas().size();
if (counts <= 0){
emptySwitch(true);
}else {
emptySwitch(false);
errorSwitch(false);
for (int i = 0; i <counts ; i++){
BeanMyTaskNet.BodyBean.DatasBean dataBean = beanMyTaskNet.getBody().getDatas().get(i);
datas.add(new BeanMyTask(ParseHtmlCode.ParseCode(dataBean.getName()) , dataBean.getWorkTasking().getId() , dataBean.getStatus() ,dataBean.getAssessType() , dataBean.getWorkTasking().getScore()+"分" , dataBean.getEndTime() , dataBean.getStatus(),dataBean.getOffice().getId()));
}
adapter.notifyDataSetChanged();
thinkNextPageNo(beanMyTaskNet.getBody().getCount());
}
}
}catch (Exception e){
e.printStackTrace();
}
}
@Override
public void insertAdapter(ListView parentListView) {
parentListView.setAdapter(adapter);
}
@Override
public String insertUrl() {
return "http://www.dbdjypt.com:81/mobile/index/WDRWlist;JSESSIONID=79d66350590d495ba328d81b8a3812b1";
}
@Override
public void clearDatas() {
datas.clear();
}
};
}
@Override
protected void init(Bundle savedInstanceState){
initDatas();
setLeftBtn(true, R.drawable.bbck, new View.OnClickListener(){
@Override
public void onClick(View v){
finish();
overridePendingTransition(R.anim.left_fadein,R.anim.left_fadeout);
}
});
setTopTitle( "測試展示的列表頁面" , true );
setRightBtn( false , 0 , null );
}
private void initDatas(){
datas = new ArrayList<>();
adapter = new CommeAdapter<BeanMyTask>(datas , AnticityTestListBar.this , R.layout.item_mytask) {
@Override
public void cover(MyViewHolder holder, BeanMyTask item) {
holder.setText(R.id.task_title , item.getTitle());
holder.setText(R.id.task_score , "任務分值:"+item.getScore());
holder.setText(R.id.task_type , "考核類別:"+item.getType());
holder.setText(R.id.task_statue , "任務狀態:"+item.getStatue());
}
};
}
這麼些程式碼就能直接完成這樣的一個完成的頁面的開發。而且類似功能的程式碼只需要繼承基類,做一個json資料解析,建立列表介面卡。
我的無敵基類。
/**
* 不必在乎你為何這麼長 因為你是萬能上帝類啊!!
*/
public abstract class TopbarBaseListActivity extends Activity{
private UsingListBySon usingListBySon;
private View emptyPage , errorPage;
private MyTaskStackTrace queue;
public static final int NO_STATUE_BAR = 0;
public static final int ALPHA_STATUE_BAR = 1;
public static final int NOMAL_STATUE_BAR = 2;
private RelativeLayout wTopbar;
private ImageButton wLeft_btn;
private TextView wTitle;
private TextView wRight_text;
private ImageButton wRight_btn;
private TwinklingRefreshLayout wRefresh;
private ListView wBeas_list;
private AVLoadingIndicatorView wAvi;
private int notePage = 1;
private boolean canNextPage = false ;
private void initBaseDatas(){
queue = new MyTaskStackTrace(5);
}
//在頁面進行初始化的操作
protected abstract UsingListBySon initDataBySon();
protected abstract void init(Bundle savedInstanceState);
//根據子類的傳參 初始化網路請求 POST 請求
public void getActivityByPost(){
wAvi.setVisibility(View.VISIBLE);
String url = usingListBySon.insertUrl();
MyHttpResponse response = new MyHttpResponse(url,"{\"pageNo\":\""+notePage+"\"}", MyHttpResponse.MY_POST, new NetWorlkCallBack(){
@Override
public void getSuccessMessage(String msg){
usingListBySon.parseJsonMessage(msg);
}
@Override
public void getErrorMsg(String msg){
wAvi.setVisibility(View.GONE);
errorPage.setVisibility(View.VISIBLE);
wRefresh.finishLoadmore();
wRefresh.finishRefreshing();
}
});
queue.addThreadToPool(response , "getListByPost");
}
//根據子類的傳參 初始化網路請求 GET 請求
public void getActivityByGet(String portName , String params){
String url = "";
MyHttpResponse response = new MyHttpResponse(url, "" , MyHttpResponse.MY_GET , new NetWorlkCallBack() {
@Override
public void getSuccessMessage(String msg){
}
@Override
public void getErrorMsg(String msg){
}
});
queue.addThreadToPool( response , "getListByGet" );
}
private void initBaseViews(){
emptyPage = findViewById(R.id.empty);
errorPage = findViewById(R.id.basy);
wTopbar = (RelativeLayout) findViewById(R.id.topbar);
wLeft_btn = (ImageButton) findViewById(R.id.left_btn);
wTitle = (TextView) findViewById(R.id.title);
wRight_text = (TextView) findViewById(R.id.right_text);
wRight_btn = (ImageButton) findViewById(R.id.right_btn);
wRefresh = (TwinklingRefreshLayout) findViewById(R.id.refresh);
wBeas_list = (ListView) findViewById(R.id.beas_list);
wAvi = (AVLoadingIndicatorView) findViewById(R.id.avi);
}
private void initBaseViewEvents(){
usingListBySon.insertAdapter(wBeas_list);
//下拉的時候重新整理 上拉的時候載入更多。。
wRefresh.setOnRefreshListener(new RefreshListenerAdapter() {
@Override
public void onLoadMore(TwinklingRefreshLayout refreshLayout) {
super.onLoadMore(refreshLayout);
if (canNextPage){
getActivityByPost();
}else{
refreshLayout.finishLoadmore();
OkToast.getInstance("已載入了全部的資料").show();
}
}
@Override
public void onRefresh(TwinklingRefreshLayout refreshLayout) {
super.onRefresh(refreshLayout);
wRefresh.finishRefreshing();
usingListBySon.clearDatas();
notePage = 1;
canNextPage = false;
getActivityByPost();
}
});
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_topbar_base_list);
initBaseDatas();
initBaseViews();
init(savedInstanceState);
this.usingListBySon = initDataBySon();
initBaseViewEvents();
getActivityByPost();
}
//設定狀態列樣式
protected void setStatueBar(int style){
switch (style){
case NO_STATUE_BAR:
try {
if ( Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP ) {
Window window = getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
}
} catch (Exception e) {
e.printStackTrace();
}
break;
case ALPHA_STATUE_BAR:
try {
if ( Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP ) {
Window window = getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
}
} catch (Exception e){
e.printStackTrace();
}
break;
}
}
//設定標題名稱
protected void setTopTitle(String topName , boolean show){
if (show){
if (!TextUtils.isEmpty(topName)){
wTitle.setText(topName);
}
}else{
wTopbar.setVisibility(View.GONE);
}
}
//設定標題欄左側的按鈕
protected void setLeftBtn(boolean show , int ResId , View.OnClickListener leftClick){
if (show){
wLeft_btn.setBackgroundResource(ResId);
wLeft_btn.setOnClickListener(leftClick);
}else {
wLeft_btn.setVisibility(View.GONE);
}
}
//設定標題欄右側的按鈕
protected void setRightBtn(boolean show , int ResId , View.OnClickListener rightClick){
wRight_text.setVisibility(View.GONE);
if (show){
wRight_btn.setBackgroundResource(ResId);
wRight_btn.setOnClickListener(rightClick);
}else {
wRight_btn.setVisibility(View.GONE);
}
}
//設定右側文字按鈕
protected void setRightText(String text , View.OnClickListener r_textClick){
wRight_btn.setVisibility(View.GONE);
wRight_text.setText(text);
wRight_text.setOnClickListener(r_textClick);
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_DOWN){
finish();
overridePendingTransition(R.anim.left_fadein,R.anim.left_fadeout);
return true;
}else {
return super.onKeyDown(keyCode , event);
}
}
@Override
public void startActivity(Intent intent) {
super.startActivity(intent);
overridePendingTransition(R.anim.right_fadein,R.anim.right_fadeout);
}
//判斷當前的狀態是否可以進行分頁 並修改相關狀態位
private void thinkNextNest(int currentPage , int counts){
if ( 10*currentPage < counts ){
canNextPage = true;
notePage = currentPage+1;
}else {
canNextPage = false;
}
}
@Override
protected void onDestroy() {
super.onDestroy();
if ( queue != null ){
queue.closeThreadPoolNow();
queue = null;
}
}
//建立一個內部介面 用於子類進行回撥業務
public interface UsingListBySon{
public void parseJsonMessage(String msg);
public void insertAdapter(ListView parentListView);
public String insertUrl();
public void clearDatas();
}
//給子類提供的一些介面性質的控制器
//資料非空的控制器
protected void emptySwitch(boolean open){
emptyPage.setVisibility(open ? View.VISIBLE : View.GONE);
}
//網路請求的控制器
protected void errorSwitch(boolean open){
errorPage.setVisibility(open ? View.VISIBLE : View.GONE);
}
//載入中。。。的控制器
protected void loadingSwitch(boolean open){
wAvi.setVisibility(open ? View.VISIBLE : View.GONE);
}
//上拉、下拉框架停止重新整理的控制器
protected void refershSwitch(boolean up){
if (up){
wRefresh.finishRefreshing();
}else {
wRefresh.finishLoadmore();
}
}
//判斷下一頁的頁碼的 邏輯
protected void thinkNextPageNo(int number){
thinkNextNest(notePage , number);
}
}
相對的列表以及所有的View都只需要給基類配置。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white"
tools:context="com.huaxinzhi.policepartybuilding.TopbarBaseListActivity">
<RelativeLayout
android:id="@+id/topbar"
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="@color/colorPrimary">
<ImageButton
android:scaleX="0.5"
android:scaleY="0.5"
android:id="@+id/left_btn"
android:layout_width="50dp"
android:layout_height="50dp"/>
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/white"
android:layout_centerInParent="true"
android:textSize="18sp"/>
<TextView
android:id="@+id/right_text"
android:gravity="center_vertical"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:textColor="@color/white"
android:layout_alignParentRight="true"
android:layout_width="wrap_content"
android:layout_height="match_parent"/>
<ImageButton
android:scaleX="0.5"
android:scaleY="0.5"
android:id="@+id/right_btn"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_alignParentRight="true"/>
</RelativeLayout>
<!--列表頁面在上帝類中進行展示-->
<com.lcodecore.tkrefreshlayout.TwinklingRefreshLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/refresh">
<ListView
android:scrollbars="none"
android:id="@+id/beas_list"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<!--資料載入中的等待動畫效果-->
<com.wang.avi.AVLoadingIndicatorView
android:visibility="gone"
app:indicatorName="BallPulseIndicator"
app:indicatorColor="@color/black"
android:id="@+id/avi"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_centerInParent="true"
style="@style/AVLoadingIndicatorView.Small"/>
<!--顯示的佔位介面-->
<include
android:visibility="gone"
android:id="@+id/empty"
layout="@layout/view_emptydata"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<include
android:visibility="gone"
android:id="@+id/basy"
layout="@layout/view_errorserver"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</com.lcodecore.tkrefreshlayout.TwinklingRefreshLayout>
</LinearLayout>
子類只需要建立一個類,在mainfest檔案種註冊,並繼承基類。對介面進行初始化,就可以實現功能完善的列表頁面。
private List<BeanMyTask> datas;
private CommeAdapter<BeanMyTask> adapter;
@Override
protected UsingListBySon initDataBySon() {
return new UsingListBySon(){
@Override
public void parseJsonMessage(String msg) {
try {
loadingSwitch(false);
refershSwitch(true);
refershSwitch(false);
Gson gson = new Gson();
BeanMyTaskNet beanMyTaskNet = gson.fromJson(msg , BeanMyTaskNet.class);
if (!beanMyTaskNet.isSuccess()){
OkToast.getInstance(beanMyTaskNet.getMsg());
}else {
int counts = beanMyTaskNet.getBody().getDatas().size();
if (counts <= 0){
emptySwitch(true);
}else {
emptySwitch(false);
errorSwitch(false);
for (int i = 0; i <counts ; i++){
BeanMyTaskNet.BodyBean.DatasBean dataBean = beanMyTaskNet.getBody().getDatas().get(i);
datas.add(new BeanMyTask(ParseHtmlCode.ParseCode(dataBean.getName()) , dataBean.getWorkTasking().getId() , dataBean.getStatus() ,dataBean.getAssessType() , dataBean.getWorkTasking().getScore()+"分" , dataBean.getEndTime() , dataBean.getStatus(),dataBean.getOffice().getId()));
}
adapter.notifyDataSetChanged();
thinkNextPageNo(beanMyTaskNet.getBody().getCount());
}
}
}catch (Exception e){
e.printStackTrace();
}
}
@Override
public void insertAdapter(ListView parentListView) {
parentListView.setAdapter(adapter);
}
@Override
public String insertUrl() {
return "http://www.dbdjypt.com:81/mobile/index/WDRWlist;JSESSIONID=79d66350590d495ba328d81b8a3812b1";
}
@Override
public void clearDatas() {
datas.clear();
}
};
}
@Override
protected void init(Bundle savedInstanceState){
initDatas();
setLeftBtn(true, R.drawable.bbck, new View.OnClickListener(){
@Override
public void onClick(View v){
finish();
overridePendingTransition(R.anim.left_fadein,R.anim.left_fadeout);
}
});
setTopTitle( "測試展示的列表頁面" , true );
setRightBtn( false , 0 , null );
}
private void initDatas(){
datas = new ArrayList<>();
adapter = new CommeAdapter<BeanMyTask>(datas , AnticityTestListBar.this , R.layout.item_mytask) {
@Override
public void cover(MyViewHolder holder, BeanMyTask item) {
holder.setText(R.id.task_title , item.getTitle());
holder.setText(R.id.task_score , "任務分值:"+item.getScore());
holder.setText(R.id.task_type , "考核類別:"+item.getType());
holder.setText(R.id.task_statue , "任務狀態:"+item.getStatue());
}
};
}