4.5.3 Go Android 下拉刷新的整理:SwipeRefreshLayout,android-Ultra-Pull-To-Refresh(ptr),PullToRefreshListView

本文主要是介绍4.5.3 Go Android 下拉刷新的整理:SwipeRefreshLayout,android-Ultra-Pull-To-Refresh(ptr),PullToRefreshListView,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1: 使用SwipeRefreshLayout 来实现下拉刷新和上拉加载, 和RecyclerView 来实现


http://blog.csdn.net/Rodulf/article/details/50514742


首先获取mSwipeRefreshLayout =(SwipeRefreshLayout)ret.findViewById(R.id.leibie_swiperefreshlayout);
然后可以设置这个SwipeRefreshLayout
mSwipeRefreshLayout.setOnRefreshListener(this);
        mSwipeRefreshLayout.setColorSchemeColors(Color.RED, Color.BLUE, Color.CYAN);
        mSwipeRefreshLayout.setSize(SwipeRefreshLayout.LARGE);


下拉刷新可以直接通过onRefresh 来执行。
然后在回调方法里面执行请求:
    @Override
    public void onRefresh() {
        HttpUtils.getLeiBieService().getLeiBie(1446).enqueue(this);
    }
}


上拉加载的实现是通过:例如这里是RecyclerView,设置一个监听器,在这里面有两个方法onScrolled,onScrollStateChanged
里面设置一个全局变量lastVisisbleItem,这个值在每次的onScrolled 里面修改,在最后的onScrollStateChanged里面 判断状态是否为SCROLL_STATE_IDEL
就是滑动结束,如果是的话,在判断这个lastViewItem是否到底了,到底了就进行加载的操作。


mRecyclerView.setOnScrollListener(new RecyclerView.OnScrollListener() {  
  
   @Override  
   public void onScrollStateChanged(RecyclerView recyclerView,  
     int newState) {  
    super.onScrollStateChanged(recyclerView, newState);  
    if (newState == RecyclerView.SCROLL_STATE_IDLE  
      && lastVisibleItem + 1 == adapter.getItemCount()) {  
     mSwipeRefreshWidget.setRefreshing(true);  
     // 此处在现实项目中,请换成网络请求数据代码,sendRequest .....  
     handler.sendEmptyMessageDelayed(0, 3000);  
    }  
   }
  


   @Override  
   public void onScrolled(RecyclerView recyclerView, int dx, int dy) {  
    super.onScrolled(recyclerView, dx, dy);  
    lastVisibleItem = mLayoutManager.findLastVisibleItemPosition();  
   }  
  
  });  


我之前的 代码:
mouge_lei_bie_detail_recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener(){
            /**
             * 在这个方法里面判断当前状态是不是SCROLL_STATE_IDLE,并且 最后一个可见的Item也就是lastVisibleItem
             * 是倒数第二个 数据 ,如果两个条件都满足,那么进行上拉加载的操作,就是发送一个 新的handle的消息。
             * 这个消息的what是ADD
             */
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
                if(newState==RecyclerView.SCROLL_STATE_IDLE&&lastVisibleItem+1==adapter.getItemCount()){
                        Message message = new Message();
                        message.what=ADD;
                        handler.sendMessage(message);
                }
            }


            /**
             * 通过recyclerView_layoutManager,这个recyclerView_layoutManager是通过下面的两句话来设置的
             * recyclerView_layoutManager = new LinearLayoutManager(this);
             * mouge_lei_bie_detail_recyclerView.setLayoutManager(recyclerView_layoutManager);
             * 得到最后一个可见的item的位置,并且把这个传递给变量lastVisibleItem ,
             */
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);
                lastVisibleItem = recyclerView_layoutManager.findLastVisibleItemPosition();
            }
        });




关于 state 还有 2中状态:
SCROLL_STATE_TOUCH_SCROLL:  // 手指触屏拉动准备滚动,只触发一次        
        SCROLL_STATE_FLING:  // 持续滚动开始,只触发一次 
        SCROLL_STATE_IDLE:  // 整个滚动事件结束,只触发一次 






2: 使用PullToRefresh 来实现下拉刷新,上拉加载,里面可以添加一个Header
http://blog.csdn.net/rodulf/article/details/50766369
首先将这个包导入为model。
<com.handmark.pulltorefresh.library.PullToRefreshListView  
        xmlns:ptr = "http://schemas.android.com/apk/res-auto"   
        android:id="@+id/pull_refresh_list"  
        android:layout_width="fill_parent"  
        android:layout_height="fill_parent"  
        android:dividerHeight="4dp"  
        android:fadingEdge="none"  
        android:fastScrollEnabled="false"  
        android:footerDividersEnabled="false"  
        android:headerDividersEnabled="false"  
        android:smoothScrollbar="true"  
        ptr:ptrMode="both"  
         />  
在布局里面要设置几个参数,最重要的是要设置这个ptrMode 为Both,ptr:ptrMode="both" 
android:fadingEdge="none"  
        android:fastScrollEnabled="false"  
        android:footerDividersEnabled="false"  
        android:headerDividersEnabled="false"  
        android:smoothScrollbar="true"  
        ptr:ptrMode="both" 


然后在activity 中获取这个PullToRefreshListView
通过 setOnRefreshListener 来添加 监听器。 监听器里面有两个方法:onPullDownToRefresh,onPullUpToRefresh


mPullRefreshListView.setOnRefreshListener(new OnRefreshListener2<ListView>() {  
            @Override  
            public void onPullDownToRefresh( PullToRefreshBase<ListView> refreshView) {  
                Toast.makeText(MainActivity.this, "onPullDownToRefresh", Toast.LENGTH_SHORT).show();  
                new GetDataTask().execute();  
            }  
            @Override  
            public void onPullUpToRefresh( PullToRefreshBase<ListView> refreshView) {  
                Toast.makeText(MainActivity.this, "onPullUpToRefresh", Toast.LENGTH_SHORT).show();  
                new GetDataTask().execute();  
            }  
        });  


获取ListView,然后就是直接使用listview的添加adapter这些东西了。


ListView actualListView =mPullRefreshListView.getRefreshableView()
通过registerForContextMenu(actualListView)来注册上下文茶蛋
mListItems = new LinkedList<String>();
mListItems.addAll();
mAdapter= new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,mListItems);
actualListView.setAdapter(mAdapter);




在 请求的里面进行添加:通过mAdapter.notifyDataSetChanged()来通知变化。


 protected void onPostExecute(String[] result) {  
              
            //向RefreshListView Item 添加一行数据  并刷新ListView  
            //mListItems.addLast("Added after refresh...");  
            mListItems.addFirst("Added after refresh...");  
            mAdapter.notifyDataSetChanged();  
  
            //通知RefreshListView 我们已经更新完成  
            // Call onRefreshComplete when the list has been refreshed.  
            mPullRefreshListView.onRefreshComplete();  
  
            super.onPostExecute(result);  
        }  


这里面可以通过,设置一个page 的全局变量,在进行数据请求的时候,
先判断这个变量,如果是1 的话,就进行重新的加载
如果是大于1的话就进行,添加的操作。




/** 
         *   设置下拉刷新和上拉加载时的 铃声(可有可无) 
         */  
        SoundPullEventListener<ListView> soundListener = new SoundPullEventListener<ListView>(this);  
        soundListener.addSoundEvent(State.PULL_TO_REFRESH, R.raw.pull_event);  
        soundListener.addSoundEvent(State.RESET, R.raw.reset_sound);  
        soundListener.addSoundEvent(State.REFRESHING, R.raw.refreshing_sound);  
        mPullRefreshListView.setOnPullEventListener(soundListener);  

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
    android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity"><!--  xmlns:ptr = "http://schemas.android.com/apk/res-auto"  为我们要使用PullToRefresh 里面一些属性需要引的命名空间 -->
    <com.handmark.pulltorefresh.library.PullToRefreshListView
        xmlns:ptr = "http://schemas.android.com/apk/res-auto"
        android:id="@+id/pull_refresh_list"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:dividerHeight="4dp"
        android:fadingEdge="none"
        android:fastScrollEnabled="false"
        android:footerDividersEnabled="false"
        android:headerDividersEnabled="false"
        android:smoothScrollbar="true"
        ptr:ptrMode="both"
        />
</RelativeLayout>



package tech.androidstudio.pulltorefresh;import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.AbsListView;
import android.widget.ArrayAdapter;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.Toast;import com.handmark.pulltorefresh.library.PullToRefreshBase;
import com.handmark.pulltorefresh.library.PullToRefreshListView;
import com.handmark.pulltorefresh.library.extras.SoundPullEventListener;import java.util.Arrays;
import java.util.LinkedList;public class MainActivity extends AppCompatActivity {static final int MENU_MANUAL_REFRESH = 0;static final int MENU_DISABLE_SCROLL = 1;static final int MENU_SET_MODE = 2;static final int MENU_DEMO = 3;private LinkedList<String> mListItems;private PullToRefreshListView mPullRefreshListView;private ArrayAdapter<String> mAdapter;private int mPage=1;@Override
    protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);mPullRefreshListView = (PullToRefreshListView) findViewById(R.id.pull_refresh_list);/**
         * 实现 接口  OnRefreshListener2<ListView>  以便与监听  滚动条到顶部和到底部
         */
        mPullRefreshListView.setOnRefreshListener(new PullToRefreshBase.OnRefreshListener2<ListView>() {@Override
            public void onPullDownToRefresh(PullToRefreshBase<ListView> refreshView) {Toast.makeText(MainActivity.this, "onPullDownToRefresh", Toast.LENGTH_SHORT).show();mPage=1;new GetDataTask().execute();}@Override
            public void onPullUpToRefresh(PullToRefreshBase<ListView> refreshView) {Toast.makeText(MainActivity.this, "onPullUpToRefresh", Toast.LENGTH_SHORT).show();mPage++;new GetDataTask().execute();}});ListView actualListView = mPullRefreshListView.getRefreshableView();// Need to use the Actual ListView when registering for Context Menu
        registerForContextMenu(actualListView);mListItems = new LinkedList<String>();mListItems.addAll(Arrays.asList(mStrings));mAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, mListItems);/**
         * Add Sound Event Listener
         */

        /**
         *   设置下拉刷新和上拉加载时的 铃声(可有可无)
         */
        SoundPullEventListener<ListView> soundListener = new SoundPullEventListener<ListView>(this);
//        soundListener.addSoundEvent(PullToRefreshBase.State.PULL_TO_REFRESH, R.raw.pull_event);
//        soundListener.addSoundEvent(PullToRefreshBase.State.RESET, R.raw.reset_sound);
//        soundListener.addSoundEvent(PullToRefreshBase.State.REFRESHING, R.raw.refreshing_sound);
        mPullRefreshListView.setOnPullEventListener(soundListener);// You can also just use setListAdapter(mAdapter) or
        // mPullRefreshListView.setAdapter(mAdapter)
        actualListView.setAdapter(mAdapter);}//模拟网络加载数据的   异步请求类
    //
    private class GetDataTask extends AsyncTask<Void, Void, String[]> {//子线程请求数据
        @Override
        protected String[] doInBackground(Void... params) {// Simulates a background job.
            try {Thread.sleep(10);} catch (InterruptedException e) {}return mStrings;}//主线程更新UI
        @Override
        protected void onPostExecute(String[] result) {//RefreshListView Item 添加一行数据  并刷新ListView
            //mListItems.addLast("Added after refresh...");
            if(mPage==1){mListItems.clear();mListItems.addAll(Arrays.asList(mStrings));}else {mListItems.addFirst("Added after refresh...");}mAdapter.notifyDataSetChanged();//通知RefreshListView 我们已经更新完成
            // Call onRefreshComplete when the list has been refreshed.
            mPullRefreshListView.onRefreshComplete();super.onPostExecute(result);}}//数据源
    private String[] mStrings = { "Abbaye de Belloc", "Abbaye du Mont des Cats", "Abertam", "Abondance", "Ackawi","Acorn", "Adelost", "Affidelice au Chablis", "Afuega'l Pitu", "Airag", "Airedale", "Aisy Cendre","Allgauer Emmentaler", "Abbaye de Belloc", "Abbaye du Mont des Cats", "Abertam", "Abondance", "Ackawi","Acorn", "Adelost", "Affidelice au Chablis", "Afuega'l Pitu", "Airag", "Airedale", "Aisy Cendre","Allgauer Emmentaler" };
}





3: 使用Utrl-PullToRefresh 来实现下拉刷新,里面可以添加一个Header
https://github.com/liaohuqiu/android-Ultra-Pull-To-Refresh


首先 导入包:in.srain.cube:ultra-ptr:1.0.11
导入布局进去in.srain.cube.views.ptr.PtrFrameLayout


<in.srain.cube.views.ptr.PtrFrameLayout
    android:id="@+id/store_house_ptr_frame"
    xmlns:cube_ptr="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"


    cube_ptr:ptr_resistance="1.7"
    cube_ptr:ptr_ratio_of_header_height_to_refresh="1.2"
    cube_ptr:ptr_duration_to_close="300"
    cube_ptr:ptr_duration_to_close_header="2000"
    cube_ptr:ptr_keep_header_when_refresh="true"
    cube_ptr:ptr_pull_to_fresh="false" >


    <LinearLayout
        android:id="@+id/store_house_ptr_image_content"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/cube_mints_333333"
        android:clickable="true"
        android:padding="10dp">


        <in.srain.cube.image.CubeImageView
            android:id="@+id/store_house_ptr_image"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
    </LinearLayout>


</in.srain.cube.views.ptr.PtrFrameLayout>




在 布局里面获取然后设置头部。


        final PtrFrameLayout ptrFrameLayout = (PtrFrameLayout)findViewById(R.id.store_house_ptr_frame);
        StoreHouseHeader header = new StoreHouseHeader(this);
        header.setPadding(0, 20, 0, 20);
        header.initWithString("Updating");


        ptrFrameLayout.setDurationToCloseHeader(2500);
        ptrFrameLayout.setHeaderView(header);
        ptrFrameLayout.addPtrUIHandler(header);




设置数据Handler:这里面有onRefreshBegin里面开始数据加载,
然后在checkCanDoRefresh里面判断是否进行刷新。


        ptrFrameLayout.setPtrHandler(new PtrHandler() {
            @Override
            public boolean checkCanDoRefresh(PtrFrameLayout frame, View content, View header) {
                return PtrDefaultHandler.checkContentCanBePulledDown(frame, content, header);
            }


            @Override
            public void onRefreshBegin(PtrFrameLayout frame) {
                mPage=1;
                new GetDataTask().execute();


                ptrFrameLayout.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        ptrFrameLayout.refreshComplete();
                    }
                }, 1500);
            }
        });


    }

完整的代码:


上拉加载和上面的一样只是在listView.setOnScrollListener(this);
注意了这里是setOnScrollListener(this),setOnScrollChangeListener(this);


@Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {
            if(scrollState==AbsListView.OnScrollListener.SCROLL_STATE_IDLE&&
                    view.getLastVisiblePosition()>=list.size()-1){
                mPage++;
                new GetDataTask().execute();
            }
    }


    @Override
    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
            

    }


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
    android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:orientation="vertical"
    android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity"><in.srain.cube.views.ptr.PtrFrameLayout
        android:id="@+id/store_house_ptr_frame"
        xmlns:cube_ptr="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"

        cube_ptr:ptr_resistance="1.7"
        cube_ptr:ptr_ratio_of_header_height_to_refresh="1.2"
        cube_ptr:ptr_duration_to_close="300"
        cube_ptr:ptr_duration_to_close_header="2000"
        cube_ptr:ptr_keep_header_when_refresh="true"
        cube_ptr:ptr_pull_to_fresh="false" ><ListView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:id="@+id/list_item"></ListView></in.srain.cube.views.ptr.PtrFrameLayout></LinearLayout>

package tech.androidstudio.ultrapulltorefreshdemo;import android.os.AsyncTask;
import android.os.Build;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.AbsListView;
import android.widget.Adapter;
import android.widget.ArrayAdapter;
import android.widget.ListView;import java.util.ArrayList;
import java.util.Arrays;import in.srain.cube.views.ptr.PtrDefaultHandler;
import in.srain.cube.views.ptr.PtrFrameLayout;
import in.srain.cube.views.ptr.PtrHandler;
import in.srain.cube.views.ptr.PtrUIHandler;
import in.srain.cube.views.ptr.header.StoreHouseHeader;
import in.srain.cube.views.ptr.indicator.PtrIndicator;public class MainActivity extends AppCompatActivity implements AbsListView.OnScrollListener {private ArrayList<String> list;private ArrayAdapter<String> adapter;private int mPage=1;@Override
    protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);ListView listView =(ListView)findViewById(android.support.v7.appcompat.R.id.list_item);list = new ArrayList<String>();adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1, list);listView.setAdapter(adapter);listView.setOnScrollListener(this);final PtrFrameLayout ptrFrameLayout = (PtrFrameLayout)findViewById(R.id.store_house_ptr_frame);StoreHouseHeader header = new StoreHouseHeader(this);header.setPadding(0, 20, 0, 20);header.initWithString("Updating");ptrFrameLayout.setDurationToCloseHeader(2500);ptrFrameLayout.setHeaderView(header);ptrFrameLayout.addPtrUIHandler(header);ptrFrameLayout.setPtrHandler(new PtrHandler() {@Override
            public boolean checkCanDoRefresh(PtrFrameLayout frame, View content, View header) {return PtrDefaultHandler.checkContentCanBePulledDown(frame, content, header);}@Override
            public void onRefreshBegin(PtrFrameLayout frame) {mPage=1;new GetDataTask().execute();ptrFrameLayout.postDelayed(new Runnable() {@Override
                    public void run() {ptrFrameLayout.refreshComplete();}}, 1500);}});}@Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {if(scrollState==AbsListView.OnScrollListener.SCROLL_STATE_IDLE&&view.getLastVisiblePosition()>=list.size()-1){mPage++;new GetDataTask().execute();}}@Override
    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {}//模拟网络加载数据的   异步请求类
    //
    private class GetDataTask extends AsyncTask<Void, Void, String[]> {//子线程请求数据
        @Override
        protected String[] doInBackground(Void... params) {// Simulates a background job.
            try {Thread.sleep(10);} catch (InterruptedException e) {}return new String[]{"hello"};}//主线程更新UI
        @Override
        protected void onPostExecute(String[] result) {if(mPage==1) {list.clear();list.addAll(Arrays.asList(array));}else{list.add("new");}adapter.notifyDataSetChanged();//RefreshListView Item 添加一行数据  并刷新ListView
            //mListItems.addLast("Added after refresh...");
            super.onPostExecute(result);}}private String[] array={"0","1","2","3","1","2","3","1","2","3","1","2","3","1","2","3","1","2","3"};}


这篇关于4.5.3 Go Android 下拉刷新的整理:SwipeRefreshLayout,android-Ultra-Pull-To-Refresh(ptr),PullToRefreshListView的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/196799

相关文章

GO语言短变量声明的实现示例

《GO语言短变量声明的实现示例》在Go语言中,短变量声明是一种简洁的变量声明方式,使用:=运算符,可以自动推断变量类型,下面就来具体介绍一下如何使用,感兴趣的可以了解一下... 目录基本语法功能特点与var的区别适用场景注意事项基本语法variableName := value功能特点1、自动类型推

GO语言中函数命名返回值的使用

《GO语言中函数命名返回值的使用》在Go语言中,函数可以为其返回值指定名称,这被称为命名返回值或命名返回参数,这种特性可以使代码更清晰,特别是在返回多个值时,感兴趣的可以了解一下... 目录基本语法函数命名返回特点代码示例命名特点基本语法func functionName(parameters) (nam

Android协程高级用法大全

《Android协程高级用法大全》这篇文章给大家介绍Android协程高级用法大全,本文结合实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友跟随小编一起学习吧... 目录1️⃣ 协程作用域(CoroutineScope)与生命周期绑定Activity/Fragment 中手

Go之errors.New和fmt.Errorf 的区别小结

《Go之errors.New和fmt.Errorf的区别小结》本文主要介绍了Go之errors.New和fmt.Errorf的区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考... 目录error的基本用法1. 获取错误信息2. 在条件判断中使用基本区别1.函数签名2.使用场景详细对

Go语言连接MySQL数据库执行基本的增删改查

《Go语言连接MySQL数据库执行基本的增删改查》在后端开发中,MySQL是最常用的关系型数据库之一,本文主要为大家详细介绍了如何使用Go连接MySQL数据库并执行基本的增删改查吧... 目录Go语言连接mysql数据库准备工作安装 MySQL 驱动代码实现运行结果注意事项Go语言执行基本的增删改查准备工作

Go中select多路复用的实现示例

《Go中select多路复用的实现示例》Go的select用于多通道通信,实现多路复用,支持随机选择、超时控制及非阻塞操作,建议合理使用以避免协程泄漏和死循环,感兴趣的可以了解一下... 目录一、什么是select基本语法:二、select 使用示例示例1:监听多个通道输入三、select的特性四、使用se

Go语言使用Gin处理路由参数和查询参数

《Go语言使用Gin处理路由参数和查询参数》在WebAPI开发中,处理路由参数(PathParameter)和查询参数(QueryParameter)是非常常见的需求,下面我们就来看看Go语言... 目录一、路由参数 vs 查询参数二、Gin 获取路由参数和查询参数三、示例代码四、运行与测试1. 测试编程路

Go语言使用net/http构建一个RESTful API的示例代码

《Go语言使用net/http构建一个RESTfulAPI的示例代码》Go的标准库net/http提供了构建Web服务所需的强大功能,虽然众多第三方框架(如Gin、Echo)已经封装了很多功能,但... 目录引言一、什么是 RESTful API?二、实战目标:用户信息管理 API三、代码实现1. 用户数据

MyBatis的xml中字符串类型判空与非字符串类型判空处理方式(最新整理)

《MyBatis的xml中字符串类型判空与非字符串类型判空处理方式(最新整理)》本文给大家介绍MyBatis的xml中字符串类型判空与非字符串类型判空处理方式,本文给大家介绍的非常详细,对大家的学习或... 目录完整 Hutool 写法版本对比优化为什么status变成Long?为什么 price 没事?怎

Android 缓存日志Logcat导出与分析最佳实践

《Android缓存日志Logcat导出与分析最佳实践》本文全面介绍AndroidLogcat缓存日志的导出与分析方法,涵盖按进程、缓冲区类型及日志级别过滤,自动化工具使用,常见问题解决方案和最佳实... 目录android 缓存日志(Logcat)导出与分析全攻略为什么要导出缓存日志?按需过滤导出1. 按