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

相关文章

Spring IoC 容器的使用详解(最新整理)

《SpringIoC容器的使用详解(最新整理)》文章介绍了Spring框架中的应用分层思想与IoC容器原理,通过分层解耦业务逻辑、数据访问等模块,IoC容器利用@Component注解管理Bean... 目录1. 应用分层2. IoC 的介绍3. IoC 容器的使用3.1. bean 的存储3.2. 方法注

MySQL 删除数据详解(最新整理)

《MySQL删除数据详解(最新整理)》:本文主要介绍MySQL删除数据的相关知识,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录一、前言二、mysql 中的三种删除方式1.DELETE语句✅ 基本语法: 示例:2.TRUNCATE语句✅ 基本语

Go语言中nil判断的注意事项(最新推荐)

《Go语言中nil判断的注意事项(最新推荐)》本文给大家介绍Go语言中nil判断的注意事项,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录1.接口变量的特殊行为2.nil的合法类型3.nil值的实用行为4.自定义类型与nil5.反射判断nil6.函数返回的

Go语言数据库编程GORM 的基本使用详解

《Go语言数据库编程GORM的基本使用详解》GORM是Go语言流行的ORM框架,封装database/sql,支持自动迁移、关联、事务等,提供CRUD、条件查询、钩子函数、日志等功能,简化数据库操作... 目录一、安装与初始化1. 安装 GORM 及数据库驱动2. 建立数据库连接二、定义模型结构体三、自动迁

Go语言代码格式化的技巧分享

《Go语言代码格式化的技巧分享》在Go语言的开发过程中,代码格式化是一个看似细微却至关重要的环节,良好的代码格式化不仅能提升代码的可读性,还能促进团队协作,减少因代码风格差异引发的问题,Go在代码格式... 目录一、Go 语言代码格式化的重要性二、Go 语言代码格式化工具:gofmt 与 go fmt(一)

Python变量与数据类型全解析(最新整理)

《Python变量与数据类型全解析(最新整理)》文章介绍Python变量作为数据载体,命名需遵循字母数字下划线规则,不可数字开头,大小写敏感,避免关键字,本文给大家介绍Python变量与数据类型全解析... 目录1、变量变量命名规范python数据类型1、基本数据类型数值类型(Number):布尔类型(bo

Android DataBinding 与 MVVM使用详解

《AndroidDataBinding与MVVM使用详解》本文介绍AndroidDataBinding库,其通过绑定UI组件与数据源实现自动更新,支持双向绑定和逻辑运算,减少模板代码,结合MV... 目录一、DataBinding 核心概念二、配置与基础使用1. 启用 DataBinding 2. 基础布局

Android ViewBinding使用流程

《AndroidViewBinding使用流程》AndroidViewBinding是Jetpack组件,替代findViewById,提供类型安全、空安全和编译时检查,代码简洁且性能优化,相比Da... 目录一、核心概念二、ViewBinding优点三、使用流程1. 启用 ViewBinding (模块级

MyBatis Plus 中 update_time 字段自动填充失效的原因分析及解决方案(最新整理)

《MyBatisPlus中update_time字段自动填充失效的原因分析及解决方案(最新整理)》在使用MyBatisPlus时,通常我们会在数据库表中设置create_time和update... 目录前言一、问题现象二、原因分析三、总结:常见原因与解决方法对照表四、推荐写法前言在使用 MyBATis

Go学习记录之runtime包深入解析

《Go学习记录之runtime包深入解析》Go语言runtime包管理运行时环境,涵盖goroutine调度、内存分配、垃圾回收、类型信息等核心功能,:本文主要介绍Go学习记录之runtime包的... 目录前言:一、runtime包内容学习1、作用:① Goroutine和并发控制:② 垃圾回收:③ 栈和