精华内容
下载资源
问答
  • 滚动条循环判断滚动条滚动到底部
    2017-11-23 16:50:25
    1. scrollTop为滚动条在Y轴上的滚动距离。
    2. clientHeight为内容可视区域的高度。
    3. scrollHeight为内容可视区域的高度加上溢出(滚动)的距离。

    滚动条到底部的条件即为scrollTop + clientHeight == scrollHeight。

    上面的公式很重要

    更多相关内容
  • 主要介绍了vue scroll滚动判断的实现(是否滚动到底部、滚动方向、滚动节流、获取滚动区域dom元素),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起...
  • 跳出循环即可。 代码: import time from lxml import etree from selenium import webdriver driver =webdriver.Chrome() driver.get('http://www.baidu.com') #定义一个初始值 temp_height=0 while True: ...

    1.浏览器自带外边的滚动条:思路就是用scrollBy一直下拉滚动条,然后scrollTop会一直变化,当scrollTop不变时,说明就到底了。跳出循环即可。

    代码:

    import time
    from selenium import webdriver
     
    driver =webdriver.Chrome()
    driver.maximize_window()
    driver.get('http://www.baidu.com') 
    driver.find_element_by_id('kw').send_keys('python滚动条的高度')
    time.sleep(1)
    driver.find_element_by_id('su').click()
    time.sleep(2)
    #定义一个初始值
    temp_height=0
     
    while True:
        #循环将滚动条下拉
        driver.execute_script("window.scrollBy(0,300)")
        #sleep一下让滚动条反应一下
        time.sleep(2)
        #获取当前滚动条距离顶部的距离
        check_height = driver.execute_script("return document.documentElement.scrollTop || window.pageYOffset || document.body.scrollTop;")
        #如果两者相等说明到底了
        if check_height==temp_height:
            break
        temp_height=check_height
        print(check_height)
    driver.quit()
    

    运行结果:

    300
    600
    900
    1199
    

    在这里插入图片描述
    2.内嵌滚动条,循环下滑到最底部
    代码:
    内嵌滚动条的demo.html的代码在https://blog.csdn.net/zhaoweiya/article/details/107162825

    import time
    from selenium import webdriver
    
    driver = webdriver.Chrome()
    driver.get('file:///C:/Users/18210/Desktop/demo.html')
    # 定义一个初始值
    temp_height = 0
    x=20
    y=20
    while True:
        js1 = "var q=document.getElementsByClassName('scroll')[0].scrollTop={}".format(x)
        driver.execute_script(js1)
        time.sleep(2)
        x+=y
        check_height = driver.execute_script(
            "return document.getElementsByClassName('scroll')[0].scrollTop;")
        if check_height == temp_height:
            break
        temp_height = check_height
        print(check_height)
    driver.quit()
    

    运行结果:

    20
    40
    60
    80
    85
    
    展开全文
  • 如下图所示,箭头所指的最后一个选项的底线与底部操作栏的上边线重叠,需要清除掉最后一个元素的底线; 想到的解决方案: 通过判断是否为最后一个元素,然后通过条件渲染(wx:if)动态添加对应的底线样式: ....

     

    问题说明:

       如下图所示,在箭头所指的最后一个选项的底线与底部操作栏的上边线重叠,需要清除掉最后一个元素的底线;

       想到的解决方案:

       通过判断是否为最后一个元素,然后通过条件渲染(wx:if)动态添加对应的底线样式: .bottom-line

     

     

    然后开始写代码,第一版如下:

     

      <view class="vote-item" wx:for="{{votes}}">
            <view class="vote-item-hd">
                <image src="{{item.data.user.avatar_url}}" mode="aspectFill"></image>
                <view class="vote-item-hd-info">
                    <view class="nickname">{{item.data.user.nick_name}}</view>
                    <view>{{item.time_for_humans}}</view>
                </view>
            </view>
            <view class="vote-item-con">
                <view class="vote-item-con-hd bottom-line">
                    {{item.data.content}}
                </view>
                <view wx:for="{{item.data.options}}" >
                    <view wx:if="{{index === item.data.options.length-1}}" class="vote-item-data" hover-class="vote-item-data-active">
                          {{item.title}}
                    </view>
                    <view wx:else class="vote-item-data bottom-line"  hover-class="vote-item-data-active">
                          {{item.title}}
                    </view>
                </view>
            </view>
            <view class="vote-item-ft top-line">
                <i class="fa fa-align-left"><text>21</text></i>
                <button open-type="share" plain="true"><i class="fa fa-retweet" bindtap="onShareAppMessage"></i></button>
            </view>
        </view>
    

      

     运行后发现:判断后的界面效果,没有任何改变;期间,我通过进行如下修改去打印:item.data.options.length

     

       <view wx:for="{{item.data.options}}" >
                    <view wx:if="{{index === item.data.options.length-1}}" class="vote-item-data" hover-class="vote-item-data-active">
                        {{item.data.options.length}}  {{item.title}}
                    </view>
                    <view wx:else class="vote-item-data bottom-line"  hover-class="vote-item-data-active">
                         {{item.data.options.length}} {{item.title}}
                    </view>
                </view>
    

     

    上述代码运行后,发现没有打印出来结果,不存在item.data.options.length

     

    研究了下文档,发现可能是外层列表的item变量名和内层列表的item冲突导致的,小程序官方文档也间接的给出了解决方案:

     

    小程序官方文档相关内容如下:

     

    通过示例,我们可以发现:可以使用wx:for-item 指定数组当前元素的变量名来解决内外层item的冲突

    于是,我通过  wx:for-item="vote" 让外层列表的变量名为vote,从而避免和内层的当前元素变量item冲突;

    顺利,通过  vote.data.options.length 获取选项的数组长度;通过条件渲染(wx:if)解决问题

     

    于是修改了下代码:

        <view class="vote-item" wx:for="{{votes}}" wx:for-item="vote">
            <view class="vote-item-hd">
                <image src="{{vote.data.user.avatar_url}}" mode="aspectFill"></image>
                <view class="vote-item-hd-info">
                    <view class="nickname">{{vote.data.user.nick_name}}</view>
                    <view>{{vote.time_for_humans}}</view>
                </view>
            </view>
            <view class="vote-item-con">
                <view class="vote-item-con-hd bottom-line">
                    {{vote.data.content}}
                </view>
                <view wx:for="{{vote.data.options}}" >
                    <view wx:if="{{index === vote.data.options.length-1}}" class="vote-item-data" hover-class="vote-item-data-active">
                         {{vote.data.options.length}}  {{item.title}}
                    </view>
                    <view wx:else class="vote-item-data bottom-line"  hover-class="vote-item-data-active">
                          {{vote.data.options.length}} {{item.title}}
                    </view>
                </view>
            </view>
            <view class="vote-item-ft top-line">
                <i class="fa fa-align-left"><text>21</text></i>
                <button open-type="share" plain="true"><i class="fa fa-retweet" bindtap="onShareAppMessage"></i></button>
            </view>
        </view>
    

      

     运行结果:重叠不见,问题解决

     

     

     

    总结:很多问题,小程序官方文档直接或间接的给出了解决方案;通过wx:for-item 指定数组当前元素的变量名,从而解决内外层item的冲突;

    从而可以在内层列表循环中获取外层列表对应的变量值,然后通过条件渲染(wx:if),从而实现对内层列表循环的最后一个元素进行动态添加边线样式( .bottom-line)。

     

    转载于:https://www.cnblogs.com/kevinCoder/p/8932197.html

    展开全文
  • /** * 底部滑动选择弹跳框 */ public class SlideDialog extends Dialog { private boolean isCancelable = false; private boolean isBackCancelable = false; private Context mContext; //上下文 private List ...

    先看效果:

     调用方法:

    SlideDialog slideDialog = new SlideDialog(this, list, false, false);
    slideDialog.setOnSelectClickListener(new SlideDialog.OnSelectListener() {
          @Override
          public void onCancel() {
              Toast.makeText(GroupFormListActivity.this, "未选择", Toast.LENGTH_SHORT).show();
                }
    
          @Override
          public void onAgree(String txt) {
              Toast.makeText(GroupFormListActivity.this, "已选中", Toast.LENGTH_SHORT).show();
                }
            });
    slideDialog.show();

     自定义SlideDialog

    package xxx.xxx.xxx.xxx;
    
    import android.app.Dialog;
    import android.content.Context;
    import android.os.Bundle;
    import android.view.Gravity;
    import android.view.View;
    import android.view.Window;
    import android.view.WindowManager;
    import android.widget.TextView;
    
    import androidx.annotation.NonNull;
    
    import com.txh.yunyao.R;
    import com.txh.yunyao.common.views.EasyPickerView;
    
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * 底部滑动选择弹跳框
     */
    public class SlideDialog extends Dialog {
        private boolean isCancelable = false;
        private boolean isBackCancelable = false;
        private Context mContext;   //上下文
        private List<String> list = new ArrayList<>(0); //数据
        private int selectPos; //默认选中位置
        private OnSelectListener mSelectListener; //监听
    
        public SlideDialog(@NonNull Context context, int view, List<String> list, boolean isCancelable, boolean isBackCancelable) {
            super(context, R.style.SlideDialog);
            this.mContext = context;
            this.isCancelable = isCancelable;
            this.isBackCancelable = isBackCancelable;
            this.list = list;
            this.selectPos = 0;
        }
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            //设置View
            setContentView(R.layout.select_slide_template);
            //设置点击物理返回键是否可关闭弹框
            setCancelable(isCancelable);
            //设置点击弹框外是否可关闭弹框
            setCanceledOnTouchOutside(isBackCancelable);
            //设置view显示位置
            Window window = this.getWindow();
            window.setGravity(Gravity.BOTTOM);
            WindowManager.LayoutParams params = window.getAttributes();
            params.width = WindowManager.LayoutParams.MATCH_PARENT;
            params.height = WindowManager.LayoutParams.WRAP_CONTENT;
            window.setAttributes(params);
            //初始化控件
            TextView tv_cancel = findViewById(R.id.tv_cancel);
            TextView tv_agree = findViewById(R.id.tv_agree);
            EasyPickerView pickerView = findViewById(R.id.pickerView);
            //取消点击事件
            tv_cancel.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    //取消
                    mSelectListener.onCancel();
                    dismiss();
                }
            });
            //确认点击事件
            tv_agree.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    //确认
                    mSelectListener.onAgree(list.get(selectPos));
                    dismiss();
                }
            });
            //设置数据
            pickerView.setDataList(list);
            //监听数据
            pickerView.setOnScrollChangedListener(new EasyPickerView.OnScrollChangedListener() {
                @Override
                public void onScrollChanged(int curIndex) {
                    //滚动时选中项发生变化
    
                }
    
                @Override
                public void onScrollFinished(int curIndex) {
                    //滚动结束
                    selectPos = curIndex;
    
                }
            });
    
        }
    
        public interface OnSelectListener {
            //取消
            void onCancel();
            //确认
            void onAgree(String txt);
        }
    
        public void setOnSelectClickListener(OnSelectListener listener) {
            this.mSelectListener = listener;
        }
    }
    

    R.style.SlideDialog 

        <style name="SlideDialog" parent="@android:style/Theme.Holo.Dialog">
            <!-- 是否有边框 -->
            <item name="android:windowFrame">@null</item>
            <!--是否在悬浮Activity之上  -->
            <item name="android:windowIsFloating">true</item>
            <!-- 标题 -->
            <item name="android:windowNoTitle">true</item>
            <!--阴影  -->
            <item name="android:windowIsTranslucent">true</item><!--半透明-->
            <!--背景透明-->
            <item name="android:windowBackground">@android:color/transparent</item>
            <!-- 还可以加入一些弹出和退出的动画 (lan)-->
        </style>

     R.layout.select_slide_template

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:background="@color/white"
        android:orientation="vertical">
    
        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginLeft="@dimen/dp_10"
            android:layout_marginRight="@dimen/dp_10"
            android:paddingTop="@dimen/dp_10"
            android:paddingLeft="@dimen/dp_15"
            android:paddingRight="@dimen/dp_15">
    
            <TextView
                android:id="@+id/tv_cancel"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@string/picture_cancel"
                android:padding="3dp"
                android:textColor="@color/black" />
    
            <TextView
                android:id="@+id/tv_agree"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentRight="true"
                android:text="@string/picture_confirm"
                android:padding="3dp"
                android:textColor="@color/black" />
        </RelativeLayout>
    
        <com.txh.yunyao.common.views.EasyPickerView
            android:id="@+id/pickerView"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:epvMaxShowNum="3"
            android:layout_marginBottom="@dimen/dp_15"
            android:layout_marginTop="@dimen/dp_15"
            app:epvTextColor="@color/black"
            app:epvTextPadding="@dimen/dp_10"
            app:epvRecycleMode="true"
            app:epvTextSize="14dp"/>
    </LinearLayout>

    自定义EasyPickerView支持以下几个属性:
    - epvTextSize:字符的大小
    - epvTextColor:字符的颜色
    - epvTextPadding:字符的间距
    - epvTextMaxScale:中间字符缩放的最大值
    - epvTextMinAlpha:两端字符最小alpha值
    - epvRecycleMode:是否为循环模式
    - epvMaxShowNum:显示多少个字符

     自定义EasyPickerView

    package xxx.xxx.xxx.xxx.xxx;
    
    import android.content.Context;
    import android.content.res.TypedArray;
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.graphics.Paint;
    import android.text.TextPaint;
    import android.util.AttributeSet;
    import android.util.TypedValue;
    import android.view.MotionEvent;
    import android.view.VelocityTracker;
    import android.view.View;
    import android.view.ViewConfiguration;
    import android.widget.Scroller;
    
    import com.txh.yunyao.R;
    
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * 滚轮视图,可设置是否循环模式,实现OnScrollChangedListener接口以监听滚轮变化
     */
    public class EasyPickerView extends View {
    
        // 文字大小
        private int textSize;
        // 颜色,默认Color.BLACK
        private int textColor;
        // 文字之间的间隔,默认10dp
        private int textPadding;
        // 文字最大放大比例,默认2.0f
        private float textMaxScale;
        // 文字最小alpha值,范围0.0f~1.0f,默认0.4f
        private float textMinAlpha;
        // 是否循环模式,默认是
        private boolean isRecycleMode;
        // 正常状态下最多显示几个文字,默认3(偶数时,边缘的文字会截断)
        private int maxShowNum;
    
        private TextPaint textPaint;
        private Paint.FontMetrics fm;
    
        private Scroller scroller;
        private VelocityTracker velocityTracker;
        private int minimumVelocity;
        private int maximumVelocity;
        private int scaledTouchSlop;
    
        // 数据
        private List<String> dataList = new ArrayList<>(0);
        // 中间x坐标
        private int cx;
        // 中间y坐标
        private int cy;
        // 文字最大宽度
        private float maxTextWidth;
        // 文字高度
        private int textHeight;
        // 实际内容宽度
        private int contentWidth;
        // 实际内容高度
        private int contentHeight;
    
        // 按下时的y坐标
        private float downY;
        // 本次滑动的y坐标偏移值
        private float offsetY;
        // 在fling之前的offsetY
        private float oldOffsetY;
        // 当前选中项
        private int curIndex;
        private int offsetIndex;
    
        // 回弹距离
        private float bounceDistance;
        // 是否正处于滑动状态
        private boolean isSliding = false;
    
        public EasyPickerView(Context context) {
            this(context, null);
        }
    
        public EasyPickerView(Context context, AttributeSet attrs) {
            this(context, attrs, 0);
        }
    
        public EasyPickerView(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
    
            TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.EasyPickerView, defStyleAttr, 0);
            textSize = a.getDimensionPixelSize(R.styleable.EasyPickerView_epvTextSize, (int) TypedValue.applyDimension(
                    TypedValue.COMPLEX_UNIT_SP, 16, getResources().getDisplayMetrics()));
            textColor = a.getColor(R.styleable.EasyPickerView_epvTextColor, Color.BLACK);
            textPadding = a.getDimensionPixelSize(R.styleable.EasyPickerView_epvTextPadding, (int) TypedValue.applyDimension(
                    TypedValue.COMPLEX_UNIT_DIP, 20, getResources().getDisplayMetrics()));
            textMaxScale = a.getFloat(R.styleable.EasyPickerView_epvTextMaxScale, 2.0f);
            textMinAlpha = a.getFloat(R.styleable.EasyPickerView_epvTextMinAlpha, 0.4f);
            isRecycleMode = a.getBoolean(R.styleable.EasyPickerView_epvRecycleMode, true);
            maxShowNum = a.getInteger(R.styleable.EasyPickerView_epvMaxShowNum, 3);
            a.recycle();
    
            textPaint = new TextPaint();
            textPaint.setColor(textColor);
            textPaint.setTextSize(textSize);
            textPaint.setAntiAlias(true);
            fm = textPaint.getFontMetrics();
            textHeight = (int) (fm.bottom - fm.top);
    
            scroller = new Scroller(context);
            minimumVelocity = ViewConfiguration.get(getContext()).getScaledMinimumFlingVelocity();
            maximumVelocity = ViewConfiguration.get(getContext()).getScaledMaximumFlingVelocity();
            scaledTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
        }
    
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            int mode = MeasureSpec.getMode(widthMeasureSpec);
            int width = MeasureSpec.getSize(widthMeasureSpec);
            contentWidth = (int) (maxTextWidth * textMaxScale + getPaddingLeft() + getPaddingRight());
            if (mode != MeasureSpec.EXACTLY) { // wrap_content
                width = contentWidth;
            }
    
            mode = MeasureSpec.getMode(heightMeasureSpec);
            int height = MeasureSpec.getSize(heightMeasureSpec);
            contentHeight = textHeight * maxShowNum + textPadding * maxShowNum;
            if (mode != MeasureSpec.EXACTLY) { // wrap_content
                height = contentHeight + getPaddingTop() + getPaddingBottom();
            }
    
            cx = width / 2;
            cy = height / 2;
    
            setMeasuredDimension(width, height);
        }
    
        @Override
        public boolean dispatchTouchEvent(MotionEvent event) {
            getParent().requestDisallowInterceptTouchEvent(true);
            return super.dispatchTouchEvent(event);
        }
    
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            addVelocityTracker(event);
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    if (!scroller.isFinished()) {
                        scroller.forceFinished(true);
                        finishScroll();
                    }
                    downY = event.getY();
                    break;
    
                case MotionEvent.ACTION_MOVE:
                    offsetY = event.getY() - downY;
                    if (isSliding || Math.abs(offsetY) > scaledTouchSlop) {
                        isSliding = true;
                        reDraw();
                    }
                    break;
    
                case MotionEvent.ACTION_UP:
                    int scrollYVelocity = 2 * getScrollYVelocity() / 3;
                    if (Math.abs(scrollYVelocity) > minimumVelocity) {
                        oldOffsetY = offsetY;
                        scroller.fling(0, 0, 0, scrollYVelocity, 0, 0, -Integer.MAX_VALUE, Integer.MAX_VALUE);
                        invalidate();
                    } else {
                        finishScroll();
                    }
    
                    // 没有滑动,则判断点击事件
                    if (!isSliding) {
                        if (downY < contentHeight / 3)
                            moveBy(-1);
                        else if (downY > 2 * contentHeight / 3)
                            moveBy(1);
                    }
    
                    isSliding = false;
                    recycleVelocityTracker();
                    break;
            }
            return true;
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            if (null != dataList && dataList.size() > 0) {
                canvas.clipRect(
                        cx - contentWidth / 2,
                        cy - contentHeight / 2,
                        cx + contentWidth / 2,
                        cy + contentHeight / 2
                );
    
                // 绘制文字,从当前中间项往前、后一共绘制maxShowNum个字
                int size = dataList.size();
                int centerPadding = textHeight + textPadding;
                int half = maxShowNum / 2 + 1;
                for (int i = -half; i <= half; i++) {
                    int index = curIndex - offsetIndex + i;
    
                    if (isRecycleMode) {
                        if (index < 0)
                            index = (index + 1) % dataList.size() + dataList.size() - 1;
                        else if (index > dataList.size() - 1)
                            index = index % dataList.size();
                    }
    
                    if (index >= 0 && index < size) {
                        // 计算每个字的中间y坐标
                        int tempY = cy + i * centerPadding;
                        tempY += offsetY % centerPadding;
    
                        // 根据每个字中间y坐标到cy的距离,计算出scale值
                        float scale = 1.0f - (1.0f * Math.abs(tempY - cy) / centerPadding);
    
                        // 根据textMaxScale,计算出tempScale值,即实际text应该放大的倍数,范围 1~textMaxScale
                        float tempScale = scale * (textMaxScale - 1.0f) + 1.0f;
                        tempScale = tempScale < 1.0f ? 1.0f : tempScale;
    
                        // 计算文字alpha值
                        float textAlpha = textMinAlpha;
                        if (textMaxScale != 1) {
                            float tempAlpha = (tempScale - 1) / (textMaxScale - 1);
                            textAlpha = (1 - textMinAlpha) * tempAlpha + textMinAlpha;
                        }
    
                        textPaint.setTextSize(textSize * tempScale);
                        textPaint.setAlpha((int) (255 * textAlpha));
    
                        // 绘制
                        Paint.FontMetrics tempFm = textPaint.getFontMetrics();
                        String text = dataList.get(index);
                        float textWidth = textPaint.measureText(text);
                        canvas.drawText(text, cx - textWidth / 2, tempY - (tempFm.ascent + tempFm.descent) / 2, textPaint);
                    }
                }
            }
        }
    
        @Override
        public void computeScroll() {
            if (scroller.computeScrollOffset()) {
                offsetY = oldOffsetY + scroller.getCurrY();
    
                if (!scroller.isFinished())
                    reDraw();
                else
                    finishScroll();
            }
        }
    
        private void addVelocityTracker(MotionEvent event) {
            if (velocityTracker == null)
                velocityTracker = VelocityTracker.obtain();
    
            velocityTracker.addMovement(event);
        }
    
        private void recycleVelocityTracker() {
            if (velocityTracker != null) {
                velocityTracker.recycle();
                velocityTracker = null;
            }
        }
    
        private int getScrollYVelocity() {
            velocityTracker.computeCurrentVelocity(1000, maximumVelocity);
            int velocity = (int) velocityTracker.getYVelocity();
            return velocity;
        }
    
        private void reDraw() {
            // curIndex需要偏移的量
            int i = (int) (offsetY / (textHeight + textPadding));
            if (isRecycleMode || (curIndex - i >= 0 && curIndex - i < dataList.size())) {
                if (offsetIndex != i) {
                    offsetIndex = i;
    
                    if (null != onScrollChangedListener)
                        onScrollChangedListener.onScrollChanged(getNowIndex(-offsetIndex));
                }
                postInvalidate();
            } else {
                finishScroll();
            }
        }
    
        private void finishScroll() {
            // 判断结束滑动后应该停留在哪个位置
            int centerPadding = textHeight + textPadding;
            float v = offsetY % centerPadding;
            if (v > 0.5f * centerPadding)
                ++offsetIndex;
            else if (v < -0.5f * centerPadding)
                --offsetIndex;
    
            // 重置curIndex
            curIndex = getNowIndex(-offsetIndex);
    
            // 计算回弹的距离
            bounceDistance = offsetIndex * centerPadding - offsetY;
            offsetY += bounceDistance;
    
            // 更新
            if (null != onScrollChangedListener)
                onScrollChangedListener.onScrollFinished(curIndex);
    
            // 重绘
            reset();
            postInvalidate();
        }
    
        private int getNowIndex(int offsetIndex) {
            int index = curIndex + offsetIndex;
            if (isRecycleMode) {
                if (index < 0)
                    index = (index + 1) % dataList.size() + dataList.size() - 1;
                else if (index > dataList.size() - 1)
                    index = index % dataList.size();
            } else {
                if (index < 0)
                    index = 0;
                else if (index > dataList.size() - 1)
                    index = dataList.size() - 1;
            }
            return index;
        }
    
        private void reset() {
            offsetY = 0;
            oldOffsetY = 0;
            offsetIndex = 0;
            bounceDistance = 0;
        }
    
        /**
         * 设置要显示的数据
         *
         * @param dataList 要显示的数据
         */
        public void setDataList(List<String> dataList) {
            this.dataList.clear();
            this.dataList.addAll(dataList);
    
            // 更新maxTextWidth
            if (null != dataList && dataList.size() > 0) {
                int size = dataList.size();
                for (int i = 0; i < size; i++) {
                    float tempWidth = textPaint.measureText(dataList.get(i));
                    if (tempWidth > maxTextWidth)
                        maxTextWidth = tempWidth;
                }
                curIndex = 0;
            }
            requestLayout();
            invalidate();
        }
    
        /**
         * 获取当前状态下,选中的下标
         *
         * @return 选中的下标
         */
        public int getCurIndex() {
            return getNowIndex(-offsetIndex);
        }
    
        /**
         * 滚动到指定位置
         *
         * @param index 需要滚动到的指定位置
         */
        public void moveTo(int index) {
            if (index < 0 || index >= dataList.size() || curIndex == index)
                return;
    
            if (!scroller.isFinished())
                scroller.forceFinished(true);
    
            finishScroll();
    
            int dy = 0;
            int centerPadding = textHeight + textPadding;
            if (!isRecycleMode) {
                dy = (curIndex - index) * centerPadding;
            } else {
                int offsetIndex = curIndex - index;
                int d1 = Math.abs(offsetIndex) * centerPadding;
                int d2 = (dataList.size() - Math.abs(offsetIndex)) * centerPadding;
    
                if (offsetIndex > 0) {
                    if (d1 < d2)
                        dy = d1; // ascent
                    else
                        dy = -d2; // descent
                } else {
                    if (d1 < d2)
                        dy = -d1; // descent
                    else
                        dy = d2; // ascent
                }
            }
            scroller.startScroll(0, 0, 0, dy, 500);
            invalidate();
        }
    
        /**
         * 滚动指定的偏移量
         *
         * @param offsetIndex 指定的偏移量
         */
        public void moveBy(int offsetIndex) {
            moveTo(getNowIndex(offsetIndex));
        }
    
        /**
         * 滚动发生变化时的回调接口
         */
        public interface OnScrollChangedListener {
            public void onScrollChanged(int curIndex);
    
            public void onScrollFinished(int curIndex);
        }
    
        private OnScrollChangedListener onScrollChangedListener;
    
        public void setOnScrollChangedListener(OnScrollChangedListener onScrollChangedListener) {
            this.onScrollChangedListener = onScrollChangedListener;
        }
    }
    

    attrs中 EasyPickerView配置

    <declare-styleable name="EasyPickerView">
        <attr name="epvTextSize" format="dimension"/>
        <attr name="epvTextColor" format="color"/>
        <attr name="epvTextPadding" format="dimension"/>
        <attr name="epvTextMaxScale" format="float"/>
        <attr name="epvTextMinAlpha" format="float"/>
        <attr name="epvRecycleMode" format="boolean"/>
        <attr name="epvMaxShowNum" format="integer"/>
    </declare-styleable>

     注:如有帮助请点点关注,如有疑问请留言。

    展开全文
  • 其特点是,给定条件成立时,反复执行某程序段,直到条件不成立为止。给定的条件称为循环条件,反复执行的程序段称为循环体。C语言提供了多种循环语句,可以组成各种不同形式的循环结构: 一 、 while循环 while...
  • 1、运算符 2、条件控制语句 3、循环控制语句 4、循环控制语句 goto label foreach /增强for
  • 需求:1、用for循环实现打印金字塔图形2、用while循环实现打印金字塔图形 public class ForWhilePyramids { public static void main(String[] args) { printForPyramids(); printWhilePyramids(); } /** ...
  • 需求:做appium自动化的过程中遇到一个问题,就是要通过滑动获取所有能获取的页面信息,直到滑动到页面底部,但是发现不知道怎么判断滑动到底部从而终止滑动的循环(appium无法得知滑动成功还是失败) appium本身...
  • 将公式快速向下填充鼠标指向已添加公式单元格右下角,当出现+号时,鼠标双击锁定被统计公式单元格=...Ctrl+↓ 跳转至底部 最左最右同理输入数字匹配文字或符号例如:输入0 显示否,输入1 显示是设置单元格格式,选择...
  • 「已完成」:我们访问过且回溯过这个节点,即该节点已经入栈,并且所有该节点的后续节点都出现栈的更底部的位置,满足拓扑排序的要求,使用 2 来表示。 现在回溯到 c,发现 c 已访问,且 c 的后续节点 d 已经完成...
  • {{item}}{{idx === orderData.tags.length-1 ? " ":" / "}} {{idx === orderData.tags.length-1 ? " “:” / "}} 这句是重点,判断是最后一个就不加 /
  • c语言程序设计之循环语句

    千次阅读 2018-12-04 21:00:22
    循环语句是C语言经常遇到的一种控制语句。... 1.while语句属于当型循环,用于循环次数未知,条件控制的循环。while循环的一般形式为: while(表达式) {  循环体语句 } 2.for语句用于实现当型循环控...
  • 分支语句和循环语句

    千次阅读 多人点赞 2021-09-24 22:14:43
    本章重点讲解分支语句和循环语句的使用 1. 什么是语句? C语言中由一个分号 ; 隔开的就是一条语句。 如下图: int a = 0; printf("Hei Tuo"); 1+2; 2. 分支语句(选择结构)
  • 文章目录1.HMLT中if/else语句的基本使用2.if---else if --- else多条件判断3.三元表达式4.switch / case 语句的应用一.常规写法二.简写switch case语句以及注意点5.while循环的使用一.基本用法二.应用案例6.do / ...
  • C语言 通过for循环绘制爱心

    千次阅读 2021-12-14 21:08:23
    其中爱心的前三行一共用了三种方法,不过第二种和第三种差不多 第一种第一个/……/中 第一种方法是一个for循环中为爱心的一行, 总共为三个for循环 因为爱心为31列而第一行中的前5格和第12到20格以及26格以后为...
  • Flutter| 事件循环,Fluture

    千次阅读 2021-11-05 16:14:18
    Dart 中,没有多线程的概念,所谓的异步操作全部都是一个线程里面执行的, 并且不会造成卡顿的原因就是事件循环(Event Loop), 如下图所示,程序的运行过程中,会有两个事件 补充上图:Micortask Queue 为...
  • C语言设计之循环语句例题

    千次阅读 2020-05-28 20:07:23
    循环语句是C语言经常遇到的一种控制语句。实际应用中的许多问题,都会涉及...在循环顶部进行循环条件测试,如果循环条件第一次测试为假,则循环体一次也不执行。for循环的一般形式为: for(表达式1;表达式2;表
  • 最近两天做了一个叫号机端的系统,内部有一块循环播放视频广告的处理,于是乎有了此篇小结 先来了解下视频广告的几个的特点 一、网络视频缓存处理 二、循环播放功能 三、动态更新视频广告 四、时效性的...
  • angular4中判断滚动条是否到达底部

    千次阅读 2018-05-08 16:13:55
    展示结果: 当滚动条接近于底部的时候控制台输出文字。一、首先通过命令新建一个项目 ng new test01ng 是angular-cli命令 ;new 是新建 ;test01 是项目名称,项目名称可以随意,不过尽量按照规范来。二、然后...
  • 本篇分析对一个列表循环执行一个功能的细节 循环列表数据的获取 如果你想发送微信好友消息,那么,我的建议是你先拿到你全部的好友的昵称列表,然后遍历去通讯录列表发送消息。 如果你不先拿所有的好友昵称,你就没...
  • 几个常用的循环语句

    千次阅读 2019-12-08 20:11:13
    循环结构是一定条件下反复执行某段程序的流程结构,被反复执行的程序被称为循环体。 循环语句是由循环体及循环的终止条件两部分组成的。 for循环 for表达式 表达式1:一般为赋值表达式,给控制变量赋初值; 表达式...
  • 首先表格上添加ref和设置高度,如下: <el-table :data="tableList" height="300" ref="table"></el-table> 循环方法如下: mounted() { // 拿到表格挂载后的真实DOM const table = this.$refs...
  • 文字无限循环滚动

    千次阅读 2019-10-30 14:05:34
    项目实现过程中,需要实现文字垂直循环滚动,第一时间想到使用css实现,不过先介绍一下js实现. 注:以下代码是基于vue的 1.js实现 原理: 实际上就是一个计时器定时执行 top ++ ,当执行到底部时,top 值置0,回到...
  • LSTM和循环网络RNN学习简记

    千次阅读 2017-07-29 11:24:39
    前馈网络回顾要理解循环网络,首先需要了解前馈网络的基础知识。这两种网络的名字都来自于它们通过一系列网络节点数学运算来传递信息的方式。前馈网络将信息径直向前递送(从不返回已经过的节点),而循环网络则将...
  • 根据特定条件,打印curl语句,然后放到 .sh文件中,用Shell来执行。 查询表***,根据产品id和结束时间(大于当前时间)查询用户。通过接口执行特定语句(就是我打印出来的语句)。 第一次代码: $config = ...
  • 当然如果落下什么了欢迎大家评论指出 目录 顺序存储线性表实现 单链表不带头标准c语言实现 单链表不带头压缩c语言实现 约瑟夫环-(数组、循环链表、数学) 线性表表示集合 线性表实现一元多项式操作 链表环问题 ...
  • 循环渲染的导航栏,每个子元素都需要通过点击事件函数修改样式,但因为循环渲染,每个子元素的点击事件函数是一样的,所以不能分别修改对应子元素的样式。通过本文,你将了解微信小程序中循环渲染wx:for的子元素如何...
  • 当前仅适用于自低向上滚动,自上向下也简单,判断items[items.length-1]的位置即可eachToY=-1 ,同时,自左向右等也一样,将相对应的Y改成x就可以了。暂时没这需求,不写这么多了 关键性代码,如下,组件onload...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 28,788
精华内容 11,515
关键字:

在循环底部判断循环条件的是