自定义布局---竖向的ViewPager

android 简单实现viewpager竖直滑动 阅读详情

效果图:

这里写图片描述

这个自定义控件涉及到的知识点:

自定义ViewGroup中onMeasure和onLayout的写法
弹性滚动Scroller的用法
速度轨迹追踪器VelocityTracker的用法
如何处理滑动事件冲突

dispatchTouchEvent:(外部拦截)告诉此ScrollLayout的父布局,什么时候该拦截触摸事件,什么时候不该拦截触摸事件

onInterceptTouchEvent:(内部拦截)ScrollLayout告诉自己什么时候要拦截内部子View的触摸事件,什么时候不要拦截内部子View的触摸事件

处理触摸滑动的思路:

  1. 先实现布局跟着手指的滑动而滑动 scrollBy
  2. 处理好边界条件(这次的处理边界,仅适用于低速滑动情况下)
  3. 如果是快速滑动VelocityTracker,必须再次考虑边界问题(上面考虑的边界问题不适用于快速滑动情况)
  4. 如果是低速滑动,要根据手指滑动方向和布局滑动的距离一起做判断,来确定,页面该滑动到那个页面,这里用到了弹性滑动Scroller
  5. 难点来了:算法,
    • 即确定当前显示的子控件的位置,
    • 确定弹性滑动滑向那个位置
      if (Math.abs(velocityY) > criticalVelocityY) {//当手指滑动速度快时,按照速度方向直接翻页
      // 重点二、快速滑动时,如何判断当前显示的是第几个控件,并且再次包含边界判断(必须包含边界判断,因为前面的边界判断,只适用于低速滑动时)
      if (shouZhiXiangXiaHuaDong) {
      if (currentPage > 1) {//★★★★★★★★边界限制,防止滑倒第一个,还继续滑动,注意★(currentPage-2)
      mScroller.startScroll(0, getScrollY(), 0, childHeight * (currentPage - 2) - getScrollY());
      currentPage--;
      }
      } else {
      if (currentPage < childCount) {//★★★★★★★边界限制,防止滑倒最后一个,还继续滑动,注意★currentPage
      mScroller.startScroll(0, getScrollY(), 0, childHeight * currentPage - getScrollY());
      currentPage++;
      }
      }
      Log.e("eee", currentPage + "");

总结

当要写一个算法时,不要着急试图一下子写出来,这样往往陷入盲目,应该是一步一步地推导,一步一步实现代码,指导最后找到规律,类似于归纳总结、通项公式的方法。

代码如下:(注释很全)

package beautlful.time.com.beautlfultime.view;

import android.content.Context;
import android.support.v4.view.ViewConfigurationCompat;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.widget.Scroller;

/**
 * 注意:此自定义viewgroup只适用于每个子控件为match_parent的情况,其实一般情况也都是这种情况
 * 注意:此自定义viewgroup,没有考虑padding的情况,使用者不要在ScrollerLayout里使用任何padding,否则你看到的不是你想要的,
 * 为了实现padding效果,你可以为ScrollerLayout的外层再套一层线性布局(或其他布局),在外层布局里使用padding值
 * 此自定义viewgroup基于郭霖博客改编,想了解具体实现细节,请参照:
 * Android Scroller完全解析,关于Scroller你所需知道的一切
 * http://blog.youkuaiyun.com/guolin_blog/article/details/48719871
 */
public class VerticalViewPager extends ViewGroup {
    int currentPage = 1;

    /**
     * 速度轨迹追踪器
     */
    private VelocityTracker mVelocityTracker;

    /**
     * 此次计算速度你想要的最大值
     */
    private final int mMaxVelocity;

    /**
     * 第一个触点的id, 此时可能有多个触点,但至少一个
     */
    private int mPointerId;

    /**
     * 计算出的竖向滚动速率
     */
    private float velocityY;

    /**
     * 手指横向滑动的速率临界值,大于这个值时,不考虑手指滑动的距离,直接滚动到最左边或者最右边
     */
    private int criticalVelocityY = 2500;

    /**
     * 用于完成滚动操作的实例
     */
    private Scroller mScroller;

    /**
     * 判定为拖动的最小移动像素数
     */
    private int mTouchSlop;

    /**
     * 手机按下时的屏幕坐标
     */
    private float mYDown;

    /**
     * 手机当时所处的屏幕坐标
     */
    private float mYMove;

    /**
     * 上次触发ACTION_MOVE事件时的屏幕坐标
     */
    private float mYLastMove;

    /**
     * 界面可滚动的顶部边界
     */
    private int topBorder;

    /**
     * 界面可滚动的底部边界
     */
    private int bottomBorder;


    /**
     * 子控件的高度(这里每个子控件高度都一样,都是match_parent)
     */
    private int childHeight;


    /**
     * 手指是否是向下滑动
     */
    private boolean shouZhiXiangXiaHuaDong;
    private int childCount;


    public VerticalViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
        // 第一步,创建Scroller的实例
        mScroller = new Scroller(context);
        ViewConfiguration configuration = ViewConfiguration.get(context);
        // 获取TouchSlop值
        mTouchSlop = ViewConfigurationCompat.getScaledPagingTouchSlop(configuration);
        //此次计算速度你想要的最大值
        mMaxVelocity = ViewConfiguration.get(context).getMaximumFlingVelocity();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        childCount = getChildCount();
        for (int i = 0; i < childCount; i++) {
            View childView = getChildAt(i);
            // 为ScrollerLayout中的每一个子控件测量大小
            measureChild(childView, widthMeasureSpec, heightMeasureSpec);
        }
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        if (changed) {
            /**
             * 当前子控件之前的所有子控件的总宽度
             */
            int preChildViewTotalHeight = 0;
            for (int i = 0; i < childCount; i++) {
                View childView = getChildAt(i);
                // 为ScrollerLayout中的每一个子控件在竖直方向上进行布局
                if (i == 0) {
                    childView.layout(
                            0,
                            0,
                            childView.getMeasuredWidth(),
                            childView.getMeasuredHeight());

                } else {
                    childView.layout(
                            0,
                            preChildViewTotalHeight,
                            childView.getMeasuredWidth(),
                            preChildViewTotalHeight + childView.getMeasuredHeight());
                }
                preChildViewTotalHeight += childView.getMeasuredHeight();

            }
            // 初始化上下边界值
            topBorder = getChildAt(0).getTop();
            bottomBorder = getChildAt(getChildCount() - 1).getBottom();

            childHeight = getChildAt(0).getMeasuredHeight();


        }
    }


    private int downX;
    private int downY;

    //        告诉此ScrollLayout的父布局,什么时候该拦截触摸事件,什么时候不该拦截触摸事件
    public boolean dispatchTouchEvent(MotionEvent ev) {
        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
                //让当前ScrollerLayout对应的父控件不要去拦截事件
                getParent().requestDisallowInterceptTouchEvent(true);
                downX = (int) ev.getX();
                downY = (int) ev.getY();
                break;
            case MotionEvent.ACTION_MOVE:
                int moveX = (int) ev.getX();
                int moveY = (int) ev.getY();

                //请求父控件ViewPager拦截触摸事件,ViewPager左右滚动时,不要触发该布局的上下滑动
                if (Math.abs(moveY - downY) < Math.abs(moveX - downX)) {
                    getParent().requestDisallowInterceptTouchEvent(false);
                } else {
                   //请求父控件ViewPager不要拦截触摸事件,ScrollerLayout自己可以上下滑动
                    getParent().requestDisallowInterceptTouchEvent(true);
                }

                break;

            case MotionEvent.ACTION_CANCEL:


                break;
            case MotionEvent.ACTION_UP:


                break;
        }
        return super.dispatchTouchEvent(ev);
    }


    //      ScrollLayout告诉自己什么时候要拦截内部子View的触摸事件,什么时候不要拦截内部子View的触摸事件
    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
                //▲▲▲1.求第一个触点的id, 此时可能有多个触点,但至少一个
                mPointerId = ev.getPointerId(0);
                mYDown = ev.getRawY();
                mYLastMove = mYDown;
                break;
            case MotionEvent.ACTION_MOVE:
                mYMove = ev.getRawY();
                float diff = Math.abs(mYMove - mYDown);
                mYLastMove = mYMove;
                // 当手指拖动值大于TouchSlop值时,认为应该进行滚动,拦截子控件的事件
                if (diff > mTouchSlop) {
                    return true;
                }
                break;
        }
        return super.onInterceptTouchEvent(ev);
    }


    @Override
    public boolean onTouchEvent(MotionEvent event) {
        //▲▲▲2.向VelocityTracker添加MotionEvent
        acquireVelocityTracker(event);
        switch (event.getAction()) {
            case MotionEvent.ACTION_MOVE:

                //▲▲▲3.求伪瞬时速度
                mVelocityTracker.computeCurrentVelocity(1000, mMaxVelocity);
                velocityY = mVelocityTracker.getYVelocity(mPointerId);

                mYMove = event.getRawY();
                int scrolledY = (int) (mYLastMove - mYMove);//注意取的是负值,因为是整个布局在动,而不是控件在动


                if (getScrollY() + scrolledY < topBorder) {// 如果已经在最上端了,就不让再往上滑动了(重点一、边界判断,直接照着这个模板抄就行)
                    scrollTo(0, topBorder);
                    return true;//★★★★★★★★★★★★★★★★这里返回true或者false实践证明都可以,但是不能什么都不返回。
                } else if (getScrollY() + getHeight() + scrolledY > bottomBorder) {//如果已经在最底部了,就不让再往底部滑动了
                    scrollTo(0, bottomBorder - getHeight());
                    return true;//★★★★★★★★★★★★★★★★★这里返回true或者false实践证明都可以,但是不能什么都不返回。
                }

                scrollBy(0, scrolledY);//手指move时,布局跟着滚动
                if (mYDown <= mYMove) {//★★★判断手指向上滑动,还是向下滑动,要用mYDown,而不是mYLastMove
                    shouZhiXiangXiaHuaDong = true;//手指往下滑动
                } else {
                    shouZhiXiangXiaHuaDong = false;//手指往上滑动
                }
                mYLastMove = mYMove;
                break;
            case MotionEvent.ACTION_UP:
//                4.▲▲▲释放VelocityTracker
                releaseVelocityTracker();

                // 第二步,当手指抬起时,根据当前的滚动值以及滚动方向来判定应该滚动到哪个子控件的界面,并且记得调用invalidate();
                if (Math.abs(velocityY) > criticalVelocityY) {//当手指滑动速度快时,按照速度方向直接翻页
//                    重点二、快速滑动时,如何判断当前显示的是第几个控件,并且再次包含边界判断(必须包含边界判断,因为前面的边界判断,只适用于低速滑动时)
                    if (shouZhiXiangXiaHuaDong) {
                        if (currentPage > 1) {//★★★★★★★★边界限制,防止滑倒第一个,还继续滑动,注意★(currentPage-2)
                            mScroller.startScroll(0, getScrollY(), 0, childHeight * (currentPage - 2) - getScrollY());
                            currentPage--;
                        }
                    } else {
                        if (currentPage < childCount) {//★★★★★★★边界限制,防止滑倒最后一个,还继续滑动,注意★currentPage
                            mScroller.startScroll(0, getScrollY(), 0, childHeight * currentPage - getScrollY());
                            currentPage++;
                        }
                    }
                    Log.e("eee", currentPage + "");
                } else {//当手指滑动速度不够快时,按照松手时,已经滑动的位置来决定翻页

//              重点三、低速滑动时,如何根据位置来判断当前显示的是第几个控件,(这里不必再次进行边界判断,因为第一次的边界判断,在这里会起到作用)
                    if ((getScrollY() >= childHeight * (currentPage - 1) + childHeight / 2 && !shouZhiXiangXiaHuaDong)) {
//                      手指向上滑动并且,滚动距离过了屏幕一半的距离
                        mScroller.startScroll(0, getScrollY(), 0, childHeight * (currentPage) - getScrollY());
                        currentPage++;

                    } else if ((getScrollY() < childHeight * (currentPage - 1) + childHeight / 2 && !shouZhiXiangXiaHuaDong)) {
//                      手指向上滑动并且,滚动距离没有过屏幕一半的距离
                        mScroller.startScroll(0, getScrollY(), 0, childHeight * (currentPage - 1) - getScrollY());

                    } else if
                            ((getScrollY() <= childHeight * (currentPage - 2) + childHeight / 2
                                    && shouZhiXiangXiaHuaDong)) {
//                       手指向下滑动并且,滚动距离过了屏幕一半的距离
                        mScroller.startScroll(0, getScrollY(), 0, childHeight * (currentPage - 2) - getScrollY());
                        currentPage--;
                    } else if
                            ((getScrollY() > childHeight * (currentPage - 2) + childHeight / 2
                                    && shouZhiXiangXiaHuaDong)) {
//                       手指向下滑动并且,滚动距离没有过屏幕一半的距离
                        mScroller.startScroll(0, getScrollY(), 0, childHeight * (currentPage - 1) - getScrollY());
                    }






                   /* if ((getScrollY() >= childHeight && !shouZhiXiangXiaHuaDong)//手指往左滑动,并且滑动完全显示第二个控件时,viewgroup滑动到最右端
                            || ((getScrollY() >= (totalChildHeight - firstChildHeight - lastChildHeight) && shouZhiXiangXiaHuaDong))) {//手指往右滑动,并且当滑动没有完全隐藏最后一个控件时,viewgroup滑动到最右端
//                    当滚动值大于某个数字时(大于第二个控件的宽度,即完全显示第二个控件时)并且是向左滑动,让这个viewgroup滑动到整个Viewgroup的最右侧,
//                    因为右侧的所有控件宽度是600,而现在已经滑动的距离是getScrollX,
//                    那么,还应该继续滑动的距离是600-getScrollX(),这里正值表示向右滑动
                        mScroller.startScroll(0,getScrollY(), 0, (totalChildHeight - firstChildHeight) - getScrollY());
                    } else if ((getScrollY() <= (totalChildHeight - firstChildHeight - lastChildHeight) && shouZhiXiangXiaHuaDong)//手指往右滑动,并且当滑动完全隐藏最后一个控件时,viewgroup滑动到最左端
                            || (getScrollY() <= childHeight && !shouZhiXiangXiaHuaDong)) {//手指往左滑动,并且滑动没有完全显示第二个控件时,viewgroup滑动到最左端

//                    当滚动值小于某个数字时,让这个viewgroup滑动到整个Viewgroup的最左侧,
//                    因为滑动到最左侧时,就是让整个viewgroup的滑动量为0,而现在已经滑动的距离是getScrollX,
//                    那么,还应该继续滑动的距离是0-getScrollX(),这里负值表示向左滑动
                        mScroller.startScroll(0,getScrollY(), 0, 0 - getScrollY());
                    }*/
                }
//                必须调用invalidate()重绘
                invalidate();
                break;

            case MotionEvent.ACTION_CANCEL:
//              5.▲▲▲释放VelocityTracker
                releaseVelocityTracker();

                break;
        }
        return super.onTouchEvent(event);
    }


    @Override
    public void computeScroll() {
        // 第三步,重写computeScroll()方法,并在其内部完成平滑滚动的逻辑
        if (mScroller.computeScrollOffset()) {
            scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
            invalidate();
        }
    }

    /**
     * @param event 向VelocityTracker添加MotionEvent
     * @see VelocityTracker#obtain()
     * @see VelocityTracker#addMovement(MotionEvent)
     */
    private void acquireVelocityTracker(final MotionEvent event) {
        if (null == mVelocityTracker) {
            mVelocityTracker = VelocityTracker.obtain();
        }
        mVelocityTracker.addMovement(event);
    }

    /**
     * 释放VelocityTracker
     *
     * @see VelocityTracker#clear()
     * @see VelocityTracker#recycle()
     */
    private void releaseVelocityTracker() {
        if (null != mVelocityTracker) {
            mVelocityTracker.clear();
            mVelocityTracker.recycle();
            mVelocityTracker = null;
        }
    }


     /*   getScrollX()指的是由viewgroup调用View的scrollTo(int x, int y)或者scrollBy(int x, int y)产生的X轴的距离
//                换句话说,就是你手指每次滑动,引起的是viewgroup累计滑动的距离,右为正
//                指的是相当于控件的左上角的为原点的坐标值
                Log.e("qqq","getX():"+event.getX());
//                指的是相当于屏幕的左上角的为原点的坐标值
                Log.e("qqq","getRawX():"+event.getRawX());*/
}

布局文件

  <beautlful.time.com.beautlfultime.view.VerticalViewPager
            android:id="@+id/verticalViewPager"
            android:layout_width="match_parent"
            android:layout_height="150dp">
            <Button
                android:layout_width="match_parent"
                android:layout_height="match_parent"
            android:background="@android:color/holo_orange_dark"
                android:text="聊天具体的信息哟" />

            <Button
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:background="@color/colorAccent"
                android:text="置顶" />

            <Button
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:background="@color/colorPrimary"
                android:text="删除" />
            <Button
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:background="@color/colorAccent"
                android:text="美好" />



        </beautlful.time.com.beautlfultime.view.VerticalViewPager>

看注释即可理解

实现Android竖直滑动的ViewPager自定义组件 在移动应用开发中,竖向滑动常常是用户与界面交互的一种直观方式。传统的横向ViewPager在某些场景下并不能满足开发者和用户的需求。本章节将介绍竖向滑动的应用场景、优势以及技术实现的可能性。随着移动应用界面的丰富和用户体验需求的提升,开发者往往需要对Android的标准组件进行定制化,以满足特定的交互需求。本章将深入探讨如何通过继承和方法重写来自定义ViewPager以实现竖向滑动功能。在自定义ViewPager时,首选的继承层次是从Android原生的ViewPager类开始。 阅读详情

相关推荐

实现Android竖向ViewPager滑动效果的完整指南

本文还有配套的精品资源,点击获取 简介:在Android应用开发中, ViewPager 用于实现页面的水平切换,但不支持竖向滑动。为满足特定设计需求,如竖向引导界面,开发者需通过自定义或第三方库来实现 ViewPager 的竖向滑动功能。本文提供一个示例,介绍如何通过继承 ViewPager 并重写其触摸事件处理方法来改变滑动方向...

weixin_33245447的博客 1298

竖向Viewpager(3D翻动效果画廊)

竖向Viewpager(3D翻动效果画廊)效果:1.竖向的Viewpager 2.3D翻动效果 3.Glide加载图片实现思路:1.Viewpager的竖向滑动:可以参照stackoverflow中的一篇帖子,这里面有很多种方式。 这里说下我的实现方式:交换触摸位置的x,y方向,利用PageTransformer的transformPage()方法,在移动过程中通过translation动态改

被代码淹没的小伙子的博客 2141

Android viewpager实现竖向滑动(支持最新的support-v13)

这个例子为VerticalViewPager。 比Jake Wharton 的 DirectionalViewPager更强大!更兼容!更稳定! 支持最新的support-v13,support-v4,你懂的。不会出现DirectionalViewPager的各种 NullPointerException!

实现垂直方向的ViewPager效果

这篇文章主要介绍下,如何实现垂直的ViewPager效果。Android为我们提供了ViewPager这种横向滑动的组件。那要是我们想实现垂直方向的ViewPager,该如何实现呢?

zhaojun的博客 2153

横向和纵向ViewPager

纵向的引导页,也就是横向的ViewPager和纵向的ViewPager 介绍参考:http://blog.youkuaiyun.com/forwardyzk/article/details/42780427

竖向viewpager

因为项目需要,要做一个竖向的viewpager,上网搜了一下,基本都是拷别人代码的搓货,没办法,只好自己做了一个,还带一点伸缩效果,如果不想要,可以去掉

竖直方向的ViewPager的实现方式

现在的ViewPager主要是横向的滑动实现,现在公司的业务需要实现竖直方向ViewPager,通过大量的寻找资料终于实现了 废话不说 直接上代码: 一:自定义viewPager package com.example.test; import java.lang.reflect.Method; import java.util.ArrayList; imp...

weixin_30568715的博客 141

垂直方向滑动的ViewPager,Android之仿网易V3.5新特性

垂直方向滑动的ViewPager,Android之仿网易V3.5新特性,源代码

垂直方向的viewPager

垂直方向的viewpager,网上也有些许实现。大多是自定义ViewGoup的,这样的话就要自己做view复用的事情了。但我思考了下发现listview不也可以做这事情吗!!于是就尝试着去实现了下,发现还真可以,效果也棒棒的。。。。。看效果是不是跟ViewPager没区别,也有回滚和快速切换。哈哈、、、最主要的是代码没几行。有下面几个问题需要解决 1.怎么让item占满整个屏幕 2.怎么滚动li

u013171787的博客 1689

Android 自定义布局竖向的ViewPager的实现

Android 自定义布局竖向的ViewPager的实现 效果图: 这个自定义控件涉及到的知识点: 自定义ViewGroup中onMeasure和onLayout的写法 弹性滚动Scroller的用法 速度轨迹追踪器VelocityTracker的用法 如何处理滑动事件冲突 dispatchTouchEvent:(外部拦截)告诉此ScrollLayout的父布局,什么时候该拦截触摸事件,什么时候不该拦截触摸事件 onInterceptTouchEvent:(内部拦截)ScrollLayout告诉自己什么时候要拦截内部子View的触摸事件,什么时候不要拦截内部子View的触摸事件 处理触

本地AI语音生成与配音工作台Pandrator:从TTS到RVC的完整实践指南

语音合成(TTS)技术通过深度学习模型将文本转换为自然语音,其核心原理涉及声学建模与波形生成。这项技术不仅提升了人机交互体验,更在内容创作领域展现出巨大价值,广泛应用于有声书制作、视频配音、虚拟助手等场景。本文聚焦于一个集成了XTTS-v2、RVC等先进模型的本地化AI语音工作台——Pandrator,它通过模块化架构将语音合成、声音克隆、音频转录与翻译等流程无缝整合,为用户提供了一个图形化、可定制的完整解决方案。文章深入解析了其基于TTS与RVC(Retrieval-based Voice Convers

weixin_42676876的博客 340

ViewPager2+TabLayout

ViewPager2+TabLayout

u013773608的博客 9551

从0开始,部署micro_ros+stm32f407+stm32cubeIDE

(5)安装依赖项rosdep时,必须处于创建的microros_ws中,因为里面有clone的src文件夹。(3)教程a中的安装docker不是必须的,取决于运行agent时是否想使用docker。(4)记得安装rosdep,并在以后的命令中将rosdep替换为rosdepc。4、运行agent,选择udp、tcp、can、串口,这里没有使用docker。(1)首先参考教程a安装虚拟机和ubuntu,注意版本选择22.04;(2)参考教程b部署micro_ros构建系统。二、安装和运行agent。

m0_37963053的博客 2236

竖直的ViewPager,上下滑动的ViewPager,VerticalViewPager ;

直接看代码吧,重写Viewpager,改变了手势和切换效果;和正常的Viewpager使用一模一样; /** * ChenboCui 竖向的Viewpager */ public class VViewPager extends ViewPager { public VViewPager(Context context) { this(context, null)...

Choi晨的博客 1977

安卓集成华为HMS Scankit实现自定义扫码功能

实现扫码功能 使用的是集成华为扫描的SDK,UI界面借鉴的是谷歌官方的Zxing项目中的自定义view,两者结合实现。 先上效果图: 先在项目根级别(build.gradle)当中配置HMS Core SDK的Maven仓地址。 // 配置HMS Core SDK的Maven仓地址。 maven {url 'https://developer.huawei.com/repo/'} // 配置HMS Core SDK的Maven仓地址。 maven {url 'https://developer.huaw

qq_47625961的博客 5512

极验滑块验证码破解与研究(一):AST还原混淆JS

极验滑块验证码破解与研究(一):AST还原混淆JS声明一、环境安装1. node安装1.1. node下载1.2. 配置环境变量1.3. node安装检测1.4. pycharm配置node环境2. babel库安装2.1. babel库安装命令2.2. babel库安装检测二、AST还原混淆JS1. 模块导入2. AST还原流程3. 复制还原需要用到的js源码4. AST还原函数详解4.1. replace_unicode4.2. replace_unicode, replace_name_array,

帯泪的鱼的博客 1万+

DirectionalViewPager支持横向和纵向的ViewPager

项目地址: [url]https://github.com/JakeWharton/Android-DirectionalViewPager[/url] 这个别人已经试过了: Android之仿网易V3.5新特性[url]http://blog.youkuaiyun.com/way_ping_li/article/details/9359191[/url] 我只是重新测试了一下,感觉可以用...

gundumw100的专栏 242

影刀rpa的使用一--读取excel表格数据并循环出每一项

1、全部展示2、运行结果展示之后可以按照各自的需求对excel中取出的数据进行处理。

qq_69268437的博客 1万+

ViewPager 实现纵向翻页切换、仿抖音视频垂直切换

博主声明: 转载请在开头附加本文链接及作者信息,并标记为转载。本文由博主威威喵原创,请多支持与指教。 本文首发于此 博主:威威喵|博客主页:https://blog.youkuaiyun.com/smile_running 抖音几乎已经成为了我们日常生活中使用比较频繁的 App,无聊之时或工作之后可以刷一刷短视频来供我们娱乐与放松。看到抖音的视屏切换效果,觉得用 ViewPag...

你若盛开,蜜蜂自来 1万+

51雾化器实现

1. 雾化器简介 雾化器是将试液雾化的一种器械。雾化器是原子化系统的重要部件,其性能对测定的精密度和化学干扰等产生显著影响。因此要求雾化器喷雾稳定、雾滴细小、均匀和雾化效率高。雾化器的类型有超声雾化器,空气压缩式雾化器,网式雾化器。超声雾化器因其价格合适,适合家用,被广泛应用于加湿器,香薰机等各种小家电,也在医疗领域有很多的应用。家用雾化器的主要器件是一枚雾化片。 家用雾化器分为两种不同类别雾化片,实孔雾化片和微孔雾化片,这两种的喷雾方法和工作原理是有所不同的。不同的雾化片需要特定的频率才能工作。 实孔雾

qq_42415953的博客 2万+

CMCC-IPC-A410串口刷机救砖教程

《CMCC-IPC-A410摄像头串口刷机指南》摘要 本指南针对2018年前老款CMCC-IPC-A410摄像头变砖/升级失败的情况,提供串口刷机方案。需准备CH340G串口模块、杜邦线、海康V5.5.82固件等工具。操作包含硬件连接(TX/RX交叉接线)、115200波特率终端配置、CTRL+U进入刷机模式,通过UPF格式化、tftp传输固件、update写入等步骤完成修复。刷机后设备恢复未激活状态,需重置密码,原定制功能可能失效。整个过程需稳定供电,耗时约15-20分钟,注意此操作将使原厂保修失效。(1

海康威视技术支持 1852

利用ViewPager打造纵向翻页切换效果、仿抖音视频垂直切换

目 录(本篇字数:861) 介绍 实现思路及代码 如何使用 介绍 抖音几乎已经成为了我们日常生活中使用比较频繁的App,无聊之时或工作之后可以刷一刷短视频来供我们娱乐与放松。看到抖音的视屏切换效果,觉得用ViewPager可以做出一样的效果。想一想之前用的ViewPager都是横向切换的,虽然很经常用,但是从来没实现过竖向的切换效果,...

weixin_34056162的博客 359

Qt | QPalette 类(调色版)

Qt | QPalette 类(调色版)

Qt历险记,专注Qt技术,三年医疗设备研发经验,1年机器视觉研发经验,半年柔性传感研发经验。 776

ViewPager2的使用

文章目录 前言 ViewPager2 介绍 ViewPager2使用 集成遇到的问题 前言 官网上显示 April 3rd, 2019 androidx.viewpager2:viewpager2:1.0.0-alpha03 is released. 也就是测试版已经第三版了,一直有关注着,今天想想就拿出来练手了,后面的优化更多的应该是bug的修复,或者增加新API,基本的使用应该是不会太大变...

shenshizhong的专栏 2954

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

Andoird 自定义ViewGroup实现竖向Viewpager

Viewpager只能横向滑动,如果是要竖向滑动呢,那么立马会想到ScrollView ,但是都知道ScrollView滑动并没有判断一页一页分屏滑动,今天来自定义一个ViewGroup实现这个功能。

kieCool的博客 627

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

ViewPager 要被废弃?官方 ViewPager2 升级版来临

热文导读|点击标题阅读大专生质问马云:你说招聘从不看文凭,为什么我投阿里石沉大海真实靠谱:百度的职级、T系列、薪资、及晋升潜规则Android Q (Android ...

Java和Android架构 2702

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

上一篇: RecyclerView上下拖动条目排序,左右划出屏幕删除条目的最简单的实现
下一篇: BroadcastReceiver简介
Android_Study_OK
博客等级 码龄11年 91粉丝 128原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值