Android之ScrollView嵌套ListView冲突

合集下载

listview的优化方案

listview的优化方案

listview的优化方案ListView是Android开发中常用的控件之一,用于展示大量数据的列表。

然而,如果不进行适当的优化,ListView可能会导致界面卡顿,滑动不流畅等问题。

因此,本文将介绍一些ListView的优化方案,帮助开发者提升应用的用户体验。

一、使用ViewHolder优化在ListView的适配器中,使用ViewHolder模式可以大幅度提升性能。

ViewHolder可以缓存每个Item的子View,避免重复的findViewById操作。

通过ViewHolder的使用,可以减少控件查找的次数,提高列表的滚动效率。

二、使用分页加载如果列表中的数据量非常大,一次性加载可能会消耗大量的内存,导致应用崩溃或卡顿。

为了解决这个问题,可以采用分页加载的方式。

将数据分批加载,每次只加载可见范围内的数据,当需要滑动到下一页时再加载下一页的数据。

这样可以降低内存压力,提高加载速度。

三、使用缓存机制ListView会在滚动过程中频繁地调用getView方法,这会导致不断地创建和销毁Item View,影响性能。

为了减少这种开销,可以使用缓存机制。

将已经创建的Item View缓存起来,当需要显示新的Item时,先从缓存中取出已有的Item View进行复用,而不是重新创建新的Item View。

这样可以减少内存的占用和创建View的时间。

四、使用异步加载如果每个Item View中包含大量的图片或其他耗时的操作,会导致列表滑动不流畅。

为了解决这个问题,可以使用异步加载的方式。

在加载图片或执行其他耗时操作时,将其放在子线程中进行,并使用回调函数将结果传递给主线程更新UI。

这样可以保证主线程的响应速度,提升用户体验。

五、减少布局层级布局层级过多也是导致ListView性能下降的一个重要因素。

每个Item View都会经过一系列的布局计算和绘制操作,层级过多会增加这些操作的复杂性。

因此,应尽量减少布局的嵌套层级,简化布局结构,提高渲染速度。

AndroidRecyclerView复用错乱通用解法详解

AndroidRecyclerView复用错乱通用解法详解

AndroidRecyclerView复⽤错乱通⽤解法详解写在前⾯:在上篇⽂章中说过对于像 RecyclerView 或者 ListView 等等此类在有限屏幕中展⽰⼤量内容的控件,复⽤的逻辑就是其核⼼的逻辑,⽽关于复⽤导致最常见的 bug 就是复⽤错乱。

在⼤上周我就遇到了⼀个很奇怪的问题,这也是我下决⼼研究RecyclerView 的原因。

⽽这篇⽂章的⽬的⾸先是讨论在 RecyclerView 复⽤错乱时,⼀些通⽤的解决思路,其次就是探究我遇到的那个奇怪的问题,帮助未来同样遇到的朋友们。

复⽤错乱的解决办法本⽂的前半部分很简单的,以为关于复⽤错乱,RecyclerView 已经有他的前辈 ListView 替它踩了很多坑了。

虽然他们的复⽤逻辑是有差异的,例如 ListView 只有两层缓存,但是 RecyclerView 可以理解为有四层;ListView 缓存的单位是 view,⽽RecyclerView 缓存的单位是 ViewHolder。

但是不管他们复⽤逻辑的差异如何,终归都是把那个缓存起来的 view 拿过来接着⽤,所以解决复⽤错乱的⽅法是⼀样的。

RecyclerView 复⽤导致错乱的原因其实就是拿出来之前的 View 来添加到新 item 上,之前 View 的状态⼀直保留着,所以也就错乱了。

不过解决起来很简单:⾸先我们以 adapter 数据的来源分为两⼤类:1.当数据来源是同步的这种情况是最简单的,你就保证当 onBindViewHolder ⽅法调⽤的时候,你的 itemview 中每个 view 的状态都有⼀个默认值。

这是什么意思呢?if ("<unknown>".equals(artists)) {holder.cbMusicState.setChecked(true);} else {holder.cbMusicState.setChecked(false);}假设我们的 holder ⾥⾯有个 Checkbox 控件,当歌⼿名为 unknown 时,Checkbox 勾选。

Android手机通讯录(源码)

Android手机通讯录(源码)

Android⼿机通讯录(源码) 简易⼿机通讯录⼀:功能模块 1.主界⾯,通过listview 展⽰所有联系⼈信息,并在没有联系⼈时给出友好提⽰ 2.主界⾯.显⽰最近查看的某个联系⼈信息 3.主界⾯,可以长按某联系⼈项,弹出菜单,删除该联系⼈;删除联系⼈后,在⼿机通知栏弹出信息给⽤户提⽰ 4.主界⾯选择分组,可以查看所有联系⼈,也可以只查看某⼀分组的联系⼈ 5.点击主界⾯的某联系⼈,可以进⼊联系⼈详情界⾯,查看联系⼈各详细信息,并可修改联系⼈各信息; 联系⼈的性别和所在分组可通过下拉菜单选择;长按电话号码,可以进⼊拨打电话功能; 修改联系⼈信息后,跳转回到主界⾯,并使⽤Toast给予⽤户提⽰ 6.主界⾯菜单栏可以添加新联系⼈,关于等功能 7.能在联系⼈详情界⾯,动态增加多个联系电话,并储存到数据库中效果图展⽰:源码下载地址:项⽬回顾: 1.scrollview嵌套listview产⽣的滑动冲突(recyclerview) 解决⽅案:listView.setOnTouchListener(new View.OnTouchListener() {@Overridepublic boolean onTouch(View v, MotionEvent event) {if(event.getAction() == MotionEvent.ACTION_UP){//点击listview⾥⾯滚动停⽌时,scrollview拦截listview的触屏事件,就是scrollview该滚动了scrollView.requestDisallowInterceptTouchEvent(false);}else{//当listview在滚动时,不拦截listview的滚动事件;就是listview可以滚动,scrollView.requestDisallowInterceptTouchEvent(true);}return false;}}); 2.关于listview 中 EditText 监听//1.在设置text前,先移除监听if (viewHodler.number.getTag() instanceof TextWatcher) {viewHodler.number.removeTextChangedListener((TextWatcher) viewHodler.number.getTag());}if (TextUtils.isEmpty(phoneNumber.getNumber())){viewHodler.number.setText("");}else {viewHodler.number.setText(phoneNumber.getNumber());}//2.新建监听类TextWatcher watcher = new TextWatcher() {@Overridepublic void beforeTextChanged(CharSequence s, int start, int count, int after) {}@Overridepublic void onTextChanged(CharSequence s, int start, int before, int count) {}@Overridepublic void afterTextChanged(Editable s) {if (TextUtils.isEmpty(s)) {phoneNumber.setNumber(null);finalViewHodler.imageView.setVisibility(View.GONE);} else {phoneNumber.setNumber(s.toString());finalViewHodler.imageView.setVisibility(View.VISIBLE);}Log.e("tag", "afterTextChanged: " +s.toString() );}};//3.添加监听器viewHodler.number.addTextChangedListener(watcher);viewHodler.number.setTag(watcher); 3.获取listview 中所有 Editext 的值 思路:在适配器中创建HashMap 在getview()⽅法中保存所有的Editext key = position value = editext 然后在通过HashMap 获取就⾏了private HashMap<Integer,EditText> edMap;@Overridepublic View getView(final int position, View convertView, ViewGroup parent) {PhoneAdapter.ViewHodler viewHodler = null;if (convertView == null) {viewHodler = new PhoneAdapter.ViewHodler();convertView = LayoutInflater.from(context).inflate(yout.phone_list_item, null, false);viewHodler.spinner = convertView.findViewById(R.id.pnone_spinner);viewHodler.number = convertView.findViewById(R.id.pnone_number);viewHodler.imageView = convertView.findViewById(R.id.imageView4);//put 保存edMap.put(position,viewHodler.number);spMap.put(position,viewHodler.spinner);convertView.setTag(viewHodler);} else {viewHodler = (PhoneAdapter.ViewHodler) convertView.getTag();edMap.put(position,viewHodler.number);spMap.put(position,viewHodler.spinner);} 4.拨打电话功能的坑public void call(String telPhone){if(checkReadPermission(Manifest.permission.CALL_PHONE,REQUEST_CALL_PERMISSION)){//要在telPhone前加上字符串tel:Intent intent = new Intent(Intent.ACTION_CALL,Uri.parse("tel:" + telPhone));startActivity(intent);}} 不让你就会见到下图:。

NestedScrollView嵌套RecyclerView

NestedScrollView嵌套RecyclerView

NestedScrollView嵌套RecyclerView 天⽓渐寒,然学习不可懈怠,记录⼀下使⽤NestedScrollView嵌套RecyclerView的两个问题,以后遇到可以来这⾥温故. 应该说在MD中,RecyclerView代替了ListView,⽽NestedScrollView代替了ScrollView,他们两个都可以⽤来跟ToolBar交互,实现上拉下滑中ToolBar的变化。

在NestedScrollView的名字中其实就可以看出他的作⽤了,Nested是嵌套的意思,⽽ToolBar基本需要嵌套使⽤.问题⼀,使⽤NestedScrollView嵌套RecyclerView时,滑动lRecyclerView列表会出现强烈的卡顿感.体验极其不流畅,这不是我们希望的.于是,百度了⼀下轻松找到解决办法.mRecyclerView.setNestedScrollingEnabled(false);加上这句之后,整个世界都平静了,⾮常流畅啊!这⾥⾯做了啥?public class RecyclerView extends ViewGroup implements ScrollingView, NestedScrollingChild {...}点击RecyclerView源码,发现其实现了ScrollingView和NestedScrollingChild两个接⼝.ScrollingView点进源码查看.public interface ScrollingView {/*** <p>Compute the horizontal range that the horizontal scrollbar* represents.</p>** @return the total horizontal range represented by the horizontal* scrollbar** @see #computeHorizontalScrollExtent()* @see #computeHorizontalScrollOffset()* @see android.widget.ScrollBarDrawable*/int computeHorizontalScrollRange();/*** <p>Compute the horizontal offset of the horizontal scrollbar's thumb* within the horizontal range. This value is used to compute the position* of the thumb within the scrollbar's track.</p>* @return the horizontal offset of the scrollbar's thumb** @see #computeHorizontalScrollRange()* @see #computeHorizontalScrollExtent()* @see android.widget.ScrollBarDrawable*/int computeHorizontalScrollOffset();/*** <p>Compute the horizontal extent of the horizontal scrollbar's thumb* within the horizontal range. This value is used to compute the length* of the thumb within the scrollbar's track.</p>** @return the horizontal extent of the scrollbar's thumb** @see #computeHorizontalScrollRange()* @see #computeHorizontalScrollOffset()* @see android.widget.ScrollBarDrawable*/int computeHorizontalScrollExtent();/*** <p>Compute the vertical range that the vertical scrollbar represents.</p>*** @return the total vertical range represented by the vertical scrollbar** <p>The default range is the drawing height of this view.</p>** @see #computeVerticalScrollExtent()* @see #computeVerticalScrollOffset()* @see android.widget.ScrollBarDrawable*/int computeVerticalScrollRange();/*** within the horizontal range. This value is used to compute the position* of the thumb within the scrollbar's track.</p>** @return the vertical offset of the scrollbar's thumb** @see #computeVerticalScrollRange()* @see #computeVerticalScrollExtent()* @see android.widget.ScrollBarDrawable*/int computeVerticalScrollOffset();/*** <p>Compute the vertical extent of the vertical scrollbar's thumb* within the vertical range. This value is used to compute the length* of the thumb within the scrollbar's track.</p>*** @return the vertical extent of the scrollbar's thumb** @see #computeVerticalScrollRange()* @see #computeVerticalScrollOffset()* @see android.widget.ScrollBarDrawable*/int computeVerticalScrollExtent();}可以看出该接⼝主要关联横向和纵向滑动距离的计算.那NestedScrollingChild呢?这是个什么?点进其源码,经过⼀顿翻译和分析,发现其定义的⽅法并不多:public interface NestedScrollingChild {/*** 设置嵌套滑动是否能⽤** @param enabled true to enable nested scrolling, false to disable*/public void setNestedScrollingEnabled(boolean enabled);/*** 判断嵌套滑动是否可⽤** @return true if nested scrolling is enabled*/public boolean isNestedScrollingEnabled();/*** 开始嵌套滑动** @param axes 表⽰⽅向轴,有横向和竖向*/public boolean startNestedScroll(int axes);/*** 停⽌嵌套滑动*/public void stopNestedScroll();/*** 判断是否有⽗View ⽀持嵌套滑动* @return whether this view has a nested scrolling parent*/public boolean hasNestedScrollingParent();/*** 在⼦View的onInterceptTouchEvent或者onTouch中,调⽤该⽅法通知⽗View滑动的距离** @param dx x轴上滑动的距离* @param dy y轴上滑动的距离* @param consumed ⽗view消费掉的scroll长度* @param offsetInWindow ⼦View的窗体偏移量* @return⽀持的嵌套的⽗View 是否处理了滑动事件*/public boolean dispatchNestedPreScroll(int dx, int dy, int[] consumed, int[] offsetInWindow);/*** ⼦view处理scroll后调⽤** @param dxConsumed x轴上被消费的距离(横向)* @param dyConsumed y轴上被消费的距离(竖向)* @param dxUnconsumed x轴上未被消费的距离* @param dyUnconsumed y轴上未被消费的距离* @param offsetInWindow ⼦View的窗体偏移量public boolean dispatchNestedScroll(int dxConsumed, int dyConsumed,int dxUnconsumed, int dyUnconsumed, int[] offsetInWindow);/*** 滑⾏时调⽤** @param velocityX x 轴上的滑动速率* @param velocityY y 轴上的滑动速率* @param consumed 是否被消费* @return true if the nested scrolling parent consumed or otherwise reacted to the fling*/public boolean dispatchNestedFling(float velocityX, float velocityY, boolean consumed);/*** 进⾏滑⾏前调⽤** @param velocityX x 轴上的滑动速率* @param velocityY y 轴上的滑动速率* @return true if a nested scrolling parent consumed the fling*/public boolean dispatchNestedPreFling(float velocityX, float velocityY);}再回头看下RecyclerView中public class RecyclerView extends ViewGroup implements ScrollingView, NestedScrollingChild { public RecyclerView(Context context, @Nullable AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);if (attrs != null) {TypedArray a = context.obtainStyledAttributes(attrs, CLIP_TO_PADDING_ATTR, defStyle, 0); mClipToPadding = a.getBoolean(0, true);a.recycle();} else {mClipToPadding = true;}setScrollContainer(true); //默认获取焦点setFocusableInTouchMode(true);final ViewConfiguration vc = ViewConfiguration.get(context);mTouchSlop = vc.getScaledTouchSlop();mMinFlingVelocity = vc.getScaledMinimumFlingVelocity();mMaxFlingVelocity = vc.getScaledMaximumFlingVelocity();setWillNotDraw(getOverScrollMode() == View.OVER_SCROLL_NEVER);mItemAnimator.setListener(mItemAnimatorListener);initAdapterManager();initChildrenHelper();// If not explicitly specified this view is important for accessibility.if (ViewCompat.getImportantForAccessibility(this)== ViewCompat.IMPORTANT_FOR_ACCESSIBILITY_AUTO) {ViewCompat.setImportantForAccessibility(this,ViewCompat.IMPORTANT_FOR_ACCESSIBILITY_YES);}mAccessibilityManager = (AccessibilityManager) getContext().getSystemService(Context.ACCESSIBILITY_SERVICE);setAccessibilityDelegateCompat(new RecyclerViewAccessibilityDelegate(this));// Create the layoutManager if specified.boolean nestedScrollingEnabled = true;if (attrs != null) {int defStyleRes = 0;TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.RecyclerView,defStyle, defStyleRes);String layoutManagerName = a.getString(R.styleable.RecyclerView_layoutManager);int descendantFocusability = a.getInt(R.styleable.RecyclerView_android_descendantFocusability, -1);if (descendantFocusability == -1) {setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS);}a.recycle();createLayoutManager(context, layoutManagerName, attrs, defStyle, defStyleRes);if (Build.VERSION.SDK_INT >= 21) {a = context.obtainStyledAttributes(attrs, NESTED_SCROLLING_ATTRS,defStyle, defStyleRes);nestedScrollingEnabled = a.getBoolean(0, true);a.recycle();setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS);} //默认⽀持嵌套滚动// Re-set whether nested scrolling is enabled so that it is set on all API levelssetNestedScrollingEnabled(nestedScrollingEnabled);} @Overridepublic void setNestedScrollingEnabled(boolean enabled) {getScrollingChildHelper().setNestedScrollingEnabled(enabled);}@Overridepublic boolean isNestedScrollingEnabled() {return getScrollingChildHelper().isNestedScrollingEnabled();}@Overridepublic boolean startNestedScroll(int axes) {return getScrollingChildHelper().startNestedScroll(axes);}@Overridepublic void stopNestedScroll() {getScrollingChildHelper().stopNestedScroll();}@Overridepublic boolean hasNestedScrollingParent() {return getScrollingChildHelper().hasNestedScrollingParent();}@Overridepublic boolean dispatchNestedScroll(int dxConsumed, int dyConsumed, int dxUnconsumed,int dyUnconsumed, int[] offsetInWindow) {return getScrollingChildHelper().dispatchNestedScroll(dxConsumed, dyConsumed,dxUnconsumed, dyUnconsumed, offsetInWindow);}@Overridepublic boolean dispatchNestedPreScroll(int dx, int dy, int[] consumed, int[] offsetInWindow) {return getScrollingChildHelper().dispatchNestedPreScroll(dx, dy, consumed, offsetInWindow);}@Overridepublic boolean dispatchNestedFling(float velocityX, float velocityY, boolean consumed) {return getScrollingChildHelper().dispatchNestedFling(velocityX, velocityY, consumed);}@Overridepublic boolean dispatchNestedPreFling(float velocityX, float velocityY) {return getScrollingChildHelper().dispatchNestedPreFling(velocityX, velocityY);}这是全部都交给getScrollingChildHelper()这个⽅法的返回对象处理了啊,看看这个⽅法是怎么实现的。

swiftui scrollview嵌套 滚动冲突 简书

swiftui scrollview嵌套 滚动冲突 简书

swiftui scrollview嵌套滚动冲突简书标题:SwiftUI ScrollView嵌套滚动冲突简述引言概述:SwiftUI是一种用于构建用户界面的现代化框架,它提供了许多强大的功能。

其中,ScrollView是一种常用的视图容器,用于显示超出屏幕范围的内容。

然而,在使用ScrollView进行嵌套时,可能会遇到滚动冲突的问题。

本文将详细介绍SwiftUI ScrollView嵌套滚动冲突的原因以及解决方案。

正文内容:1. 嵌套滚动冲突的原因1.1 内容超出屏幕范围1.2 嵌套的ScrollView之间的滚动事件冲突1.3 SwiftUI的滚动冲突处理机制2. 解决方案2.1 使用GeometryReader获取父视图的尺寸2.2 使用PreferenceKey解决滚动冲突2.3 使用UIScrollView嵌套解决滚动冲突2.4 使用嵌套的LazyVStack替代ScrollView2.5 使用List替代ScrollView3. 解决方案详细阐述3.1 使用GeometryReader获取父视图的尺寸:通过GeometryReader可以获取到父视图的尺寸,从而可以根据需要调整子视图的布局,避免滚动冲突的问题。

3.2 使用PreferenceKey解决滚动冲突:PreferenceKey是一种用于在视图层次结构中传递数据的机制,可以通过它来解决嵌套ScrollView之间的滚动冲突问题。

3.3 使用UIScrollView嵌套解决滚动冲突:在需要嵌套的ScrollView外部包裹一个UIScrollView,并通过设置UIScrollView的isScrollEnabled属性来实现滚动冲突的解决。

3.4 使用嵌套的LazyVStack替代ScrollView:LazyVStack是SwiftUI中一种用于垂直布局的视图容器,可以替代ScrollView来避免滚动冲突。

3.5 使用List替代ScrollView:List是SwiftUI中一种用于显示列表数据的视图容器,它内部已经实现了滚动冲突的解决,因此可以替代ScrollView来避免滚动冲突。

NestedScrollView+Recyclerview下滑卡顿解决方法

NestedScrollView+Recyclerview下滑卡顿解决方法

NestedScrollView+Recyclerview下滑卡顿解决⽅法⼤家在进⾏安卓开发⽤到NestedScrollView+Recyclerview的时候,经常出现的情况就是加载下滑的时候没有任何问题,很流畅,但是在下滑以后明显出现了卡顿的情况,⼩编根绝这个问题,给⼤家再来的解决⽅法,⼀起来学习下。

我们先来看下这个BUG的表现:1.滑动卡顿,2.加载下滑时流畅,下滑时明显的卡顿3.进⼊页⾯时直接加载RecyclerView部分的内容(这⾥我理解为控件惯性,不知道对不对-------尴尬)下⾯我们⼀⼀来解决这些问题在开发项⽬中,涉及到到商品详情页,新闻详情页等的页⾯时,通常情况下,商品详情页的底部会附上商品的评论或者是相关商品的的推荐,或者是相关性的⽂章.那么我们就会⽤到列表的RecyclerView,在头部可能是⼀些⽐较复杂的多种界⾯,可能采⽤⽐较简单的⽅法来处理,那就是NestedScrollView+Recyclerview,这这种⽅式⽐较直观和⽅便操作.⽐如像下⾯的代码<?xml version="1.0" encoding="utf-8"?><android.support.v4.widget.NestedScrollViewxmlns:android="/apk/res/android"xmlns:app="/apk/res-auto"android:id="@+id/scrollView_comment"android:layout_width="match_parent"android:layout_height="match_parent"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical">.....此处省略<LinearLayoutandroid:layout_width="match_parent"android:layout_height="44dp"android:gravity="center"><LinearLayoutandroid:layout_width="wrap_content"android:layout_height="wrap_content"><ImageViewandroid:layout_width="20dp"android:layout_height="20dp"android:src="@color/text_msg_33"/><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginLeft="12dp"android:layout_marginRight="12dp"android:text="1"android:textColor="#8c8c8c"android:textSize="15sp"/><ImageViewandroid:layout_width="20dp"android:layout_height="20dp"android:src="@color/text_msg_33"/></LinearLayout><TextViewandroid:layout_width="wrap_content"android:layout_height="20dp"android:layout_marginRight="10dp"android:background="@drawable/bg_shop_card"android:gravity="center"android:paddingLeft="8dp"android:paddingRight="8dp"android:text="加⼊购物车"android:textColor="@color/white"android:textSize="14sp"/></LinearLayout><Viewandroid:layout_width="match_parent"android:layout_height="10dp"android:background="#f2f2f2"/><LinearLayoutandroid:layout_width="match_parent"android:layout_height="35dp"android:gravity="center_vertical"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginLeft="11dp"android:text="⽤户评价"android:textColor="#666666"android:textSize="13sp"/><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginLeft="@dimen/line_1px"android:layout_marginRight="20dp"android:text="(21313)"android:textColor="#666666"android:textSize="13sp"/></LinearLayout><Viewandroid:layout_width="match_parent"android:layout_height="0.5dp"android:background="#dcdcdc"/><android.support.v7.widget.RecyclerViewandroid:id="@+id/recycler_seller_comment"android:layout_width="match_parent"android:layout_height="match_parent"android:descendantFocusability="blocksDescendants"android:nestedScrollingEnabled="false"/><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="查看更多"android:textColor="#8c8c8c"android:textSize="13sp"/></LinearLayout></android.support.v4.widget.NestedScrollView>⾸先.滑动动卡顿的问题.在布局⽂件中添加android:nestedScrollingEnabled="false"这⼀属性或者通过代码设置也是可以的,mRecycler.setNestedScrollingEnabled(false);这样滑动的时候就不会出现有卡顿的现象.其次是加载上下滑动加载流畅时通过代码mRecycler.setHasFixedSize(false);对于第三种现象,我找了很多⽅法,都以失败⽽告终,其实出现这种情况是应为Recyclerview在加载数据的时候获取到了焦点导致,所以只需要在对RecylerView在带中设置不能获取焦点即可.添加以下代码mRecycler.setFocusable(false);以上是⼩编测试过的解决⽅法,接下来,我们再给⼤家分享⼀篇简单的⽅法代码:最开始使⽤ScrollView的时候嵌套ListView会出现item显⽰不全等⼀些问题,现在google提供NestedScrollView已经可以解决该问题,但是在使⽤NestedScrollView嵌套RecyclerView的时候会发现我们在RecyclerView上滑动的时候没有了滚动的效果,查看⽂档找到的解决办法:LinearLayoutManager layoutManager = new LinearLayoutManager(this);layoutManager.setSmoothScrollbarEnabled(true);layoutManager.setAutoMeasureEnabled(true);recyclerView.setLayoutManager(layoutManager);recyclerView.setHasFixedSize(true);recyclerView.setNestedScrollingEnabled(false);就在⼩编完稿的时候,⼜发现了两种⽅法,⼤神真的是多啊,⼀起整理后分享给你当ScrollView嵌套RecyclerView时,会出现滑动卡顿,不平滑的效果。

android 常见view的用法

android 常见view的用法

android 常见view的用法常见的Android View的用法有:1. TextView(文本视图):用于显示文本内容,可以设置字体、颜色、字体大小等属性。

2. ImageView(图片视图):用于显示图片,可以设置图片资源、缩放类型、背景等属性。

3. Button(按钮):用于触发点击事件,可以设置文本、背景、点击效果等属性。

4. EditText(编辑文本视图):用于输入文本内容,可以设置提示文本、输入类型、最大长度等属性。

5. RadioButton(单选按钮):用于在多个选项中选择一个,可以设置文本、选中状态等属性。

6. CheckBox(复选框):用于在多个选项中选择多个,可以设置文本、选中状态等属性。

7. ProgressBar(进度条):用于显示操作进度,可以设置进度值、样式、颜色等属性。

8. SeekBar(滑动条):用于选择数值范围,可以设置最小值、最大值、当前值等属性。

9. ListView(列表视图):用于显示大量数据列表,可以自定义每一项的布局和交互。

10. GridView(网格视图):用于显示数据的表格布局,可以自定义每个单元格的布局和交互。

11. RecyclerView(可复用列表视图):Android的推荐使用的列表视图,功能更强大、性能更优。

12. WebView(网页视图):用于显示网页内容,可以加载本地或远程网页。

13. ScrollView(滚动视图):用于包裹超出屏幕大小的内容,并通过滑动来查看全部内容。

14. LinearLayout(线性布局):用于按照水平或垂直方向排列子视图。

15. RelativeLayout(相对布局):用于按照相对位置摆放子视图,灵活性更高。

16. FrameLayout(帧布局):用于叠加子视图,通常用于显示单个子视图或切换视图。

这些是Android中常见的View,开发者可以根据实际需求选择合适的View并设置相应的属性,实现各种不同的界面效果。

ScrollView中嵌套recycleView出现的不显示,显示不全,终极解决方案

ScrollView中嵌套recycleView出现的不显示,显示不全,终极解决方案

ScrollView中嵌套recycleView出现的不显⽰,显⽰不全,终极解决⽅案 最近公司项⽬中⽤到了ScrollView去嵌套recycleView, 最开始我天真的把recycleView直接放⼊scrollView中,结果可想⽽知,什么都不显⽰,瞬间懵逼,我⼼想应该是和嵌套ListView差不多吧,看来需要重写recycleView中onMeasure()⽅法,像这样:@Overrideprotected void onMeasure(int widthSpec, int heightSpec) {int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,MeasureSpec.AT_MOST);super.onMeasure(widthSpec, expandSpec);}结果:运⾏还是什么都没有。

没办法上⽹搜索解决⽅案,⼀搜看来⽹友很多跟我有⼀样的需求,⽹上也有⼤神提供的解决⽅案例如这样:<RelativeLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:descendantFocusability="blocksDescendants"><android.support.v7.widget.RecyclerViewandroid:id="@+id/menuRv"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginLeft="@dimen/margin_16"android:layout_marginRight="@dimen/margin_16"/></RelativeLayout>我的结果: 运⾏还是原来⼀样没有任何反应.注意:你们可以试试,说是解决在Android6.0显⽰不全的问题,如果成功了那祝贺你们,如果没有成功的话就跟着我往下看。

scroll-view用法

scroll-view用法

scroll-view用法ScrollView是一个可以容纳更多内容的可滚动视图,常用于展示超出屏幕大小的内容或者内容较多的页面。

下面是ScrollView的基本用法:1. 在布局文件中添加ScrollView:```xml<ScrollViewandroid:layout_width="match_parent"android:layout_height="match_parent"><!-- 在这里添加要滚动的内容 --></ScrollView>```2. ScrollView只能有一个直接子元素,因此如果需要添加多个视图,需要在ScrollView中嵌套一个垂直线性布局或其他布局容器,然后将要滚动的内容放在该容器中。

3. 在ScrollView中添加要显示的内容,比如文本视图(TextView)、图片视图(ImageView)、列表视图(ListView/RecyclerView)等。

4. 根据需要可以设置ScrollView的属性,如背景颜色、内边距等。

```xml<ScrollViewandroid:layout_width="match_parent"android:layout_height="match_parent"android:background="#FFFFFF"android:padding="16dp"><!-- 在这里添加要滚动的内容 --></ScrollView>```需要注意的是,ScrollView会将所有的子视图一次性全部加载到内存中,如果子视图的数量较多或者子视图中包含较大的图片等资源,可能会导致内存占用过大或者加载过慢的问题。

在这种情况下,可以考虑使用RecyclerView等更高效的滚动视图替代ScrollView。

AndroidBottomSheet效果的两种实现方式

AndroidBottomSheet效果的两种实现方式

AndroidBottomSheet效果的两种实现⽅式本⽂介绍了Android BottomSheet效果的两种实现⽅式,分享给⼤家,具体如下:BottomSheet效果BottomSheet的效果是指从屏幕底部向上滑的效果,是MaterialDesign风格的⼀种,视觉效果如下:BottomSheet效果实现这种效果有⼏种不同的⽅式,如果是在⼀个固定的页⾯上添加这种效果,可以在该页⾯布局中添加BoottomSheet相关的控件。

如果是作为通⽤控件来提供给不同页⾯使⽤,则可以使⽤BottomSheetDialog实现,本⽂将对两种⽅法进⾏讲解,其中会讲到⼀些使⽤上的细节,处理不好这些细节,会出现⾮常怪异的效果。

单页⾯添加BottomSheet效果⾸先引⼊依赖包:compile 'com.android.support:design:27.1.1'页⾯布局如下:<?xml version="1.0" encoding="utf-8"?><android.support.design.widget.CoordinatorLayout xmlns:android="/apk/res/android"xmlns:app="/apk/res-auto"android:orientation="vertical"android:layout_width="match_parent"android:layout_height="match_parent"><LinearLayoutandroid:id="@+id/customActionWebView"android:orientation="vertical"android:layout_width="match_parent"android:layout_height="match_parent"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="⽂本⼀"/><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="⽂本⼆"/></LinearLayout><android.support.v4.widget.NestedScrollViewandroid:id="@+id/nested_scroll_view"android:layout_width="match_parent"android:layout_height="match_parent"app:behavior_hideable="true"app:behavior_peekHeight="150dp"android:layout_gravity="bottom"app:layout_behavior="@string/bottom_sheet_behavior"><WebViewandroid:id="@+id/web_view"android:layout_width="match_parent"android:layout_height="match_parent"></WebView></android.support.v4.widget.NestedScrollView></android.support.design.widget.CoordinatorLayout>根布局需要使⽤CoordinatorLayout,同时在其直接⼦布局——这⾥是NestedScrollView——⾥添加behaviorapp:layout_behavior = "@string/bottom_sheet_behavior" 。

NestedScrollView、ScrollView加载完自动滑动至底部问题的解决方案

NestedScrollView、ScrollView加载完自动滑动至底部问题的解决方案

NestedScrollView、ScrollView加载完⾃动滑动⾄底部问题的解决⽅案正常情况下,由于NestedScrollView/ScrollView 嵌套RecyclerView,可能会导致Recyclerview占据焦点导致整个NestedScrollView/ScrollView内容上滑。

此问题的解决⽅案如下:1. 在根布局设置android:descendantFocusability=”blocksDescendants” ;android:descendantFocusability 有三种值:beforeDescendants:viewgroup会优先其⼦类控件⽽获取到焦点afterDescendants:viewgroup只有当其⼦类控件不需要获取焦点时才获取焦点blocksDescendants:viewgroup会覆盖⼦类控件⽽直接获得焦点这种⽅法,会造成页⾯中Editext焦点被抢导致⽆法输⼊,需要⽤到第⼆种⽅法。

2, 对于有Editext的页⾯需要在根布局使⽤ :android:focusable="true"android:focusableInTouchMode="true"3. 在NestedScrollView/ScrollView顶部第⼀个控件使⽤ :android:focusable="true"android:focusableInTouchMode="true"----------------------------------------------- 分割线 -----------------------------------------------------2019-12-5 补充:在实际开发中,不建议使⽤ScrollView包裹ListView/GridView/ExpandableListView,因为这样会把ListView的所有Item都加载到内存中,需要消耗巨⼤的内存和CPU去绘制画⾯。

scroll-view滚动使用

scroll-view滚动使用

scroll-view滚动使⽤scroll-view是⼀个uni-app提供滚动的组件。

对于滚动原理我们需要有⼀定的认知,只有当⼦元素的内容⼤于⽗元素的内容时,才能进⾏滚动。

唯⼀强调的点: 在scroll-view中貌似不能使⽤flex布局,即使使⽤后也⽆法出现相应的结果。

另外在scroll-view标签上不需要设置over-flow:hidden,当我们设置了scroll-view的⾼度后,即使单个元素⾼度⼤于scroll-view的⾼度,也不会超出scroll-view内容显⽰。

当我们需要使⽤横向滚动时,我们不能使⽤flex来实现,解决的办法是:⾸先在scroll-view中设置属性:scroll-x="true"。

然后在scroll-view中设置css:.scroll-view{white-space:nowrap; //必须添加,否则⽆法出现滚动效果。

} 然后将scroll-view中的⼦元素设置为inline-block即可。

案例代码,我⾃⼰⽤flex⽆法实现横向滚动,故采⽤inline-block。

如果您看到这篇⽂章,并且使⽤flex实现了scroll-view横向滚动,请留⾔告知解决⽅法,谢谢!!<view class="s-c-title">x轴滚动</view><scroll-view class="s-c-list-x" scroll-x="true" scroll-left="400"><view class="s-c-l-item">01</view><view class="s-c-l-item">02</view><view class="s-c-l-item">03</view></scroll-view>/**css样式**/.s-c-list-x{/* display: flex; *//* flex-direction: row; *//* flex-wrap: nowrap; */white-space: nowrap;width: 100%;height: 450upx;background-color: #1abc9c;color:#fff;overflow: hidden;border-radius: 10upx;}.s-c-list-x .s-c-l-item{display: inline-block;width: 100%;/* height: inherit; */height: 450upx;background-color:#27ae60;text-align: center;line-height: 450upx;font-size: 100upx;}.s-c-list-x .s-c-l-item:nth-child(2n){background-color: #e74c3c;}/**css 样式**/。

cannot resolve class constraintlayout

cannot resolve class constraintlayout

cannot resolve class constraintlayout 在开发Android应用程序的过程中,经常会使用到ConstraintLayout布局,这种布局方式可以简单地实现复杂的UI界面,提高开发效率。

但是,在使用过程中,我们有时会遇到“cannot resolve class ConstraintLayout”的错误提示,这时该怎么办呢?首先,我们需要确认一下是否已经在项目的build.gradle文件中正确地添加了ConstraintLayout依赖。

在dependencies中添加以下依赖即可:```implementation'androidx.constraintlayout:constraintlayout:2.0.4'```如果已经添加了依赖,还是出现了错误提示,那可能是因为Android Studio的缓存导致的。

此时,可以尝试清除Android Studio 的缓存,具体方法如下:1. 关闭Android Studio2. 进入项目根目录,找到.gradle文件夹3. 进入.gradle文件夹,找到caches文件夹4. 删除caches文件夹下的所有子文件夹5. 重新启动Android Studio如果以上方法还是无法解决问题,可能是因为IDE没有正确地加载项目中的库文件。

此时,可以尝试在Android Studio的菜单栏中选择File -> Invalidate Caches/Restart,然后重新启动Android Studio,重新加载项目。

另外,在使用ConstraintLayout时,还需要注意一些细节问题。

比如,在使用约束时,应该使用“com.google.android.material.button.MaterialButton”,而不是“android.widget.Button”,否则可能会出现错误提示。

此外,还需要注意约束的方向和优先级,不同的设置会导致不同的布局效果。

AndroidApp中ViewPager所带来的滑动冲突问题解决方法

AndroidApp中ViewPager所带来的滑动冲突问题解决方法

AndroidApp中ViewPager所带来的滑动冲突问题解决⽅法叙述滑动冲突可以说是⽇常开发中⽐较常见的⼀类问题,也是⽐较让⼈头疼的⼀类问题,尤其是在使⽤第三⽅框架的时候,两个原本完美的控件,组合在⼀起之后,忽然发现整个世界都不好了。

关于滑动冲突滑动冲突分类:滑动冲突,总的来说就是两类。

1.同⽅向滑动冲突⽐如ScrollView嵌套ListView,或者是ScrollView嵌套⾃⼰2.不同⽅向滑动冲突⽐如ScrollView嵌套ViewPager,或者是ViewPager嵌套ScrollView,这种情况其实很典型。

现在⼤部分应⽤最外层都是ViewPager+Fragment 的底部切换(⽐如微信)结构,这种时候,就很容易出现滑动冲突。

不过ViewPager⾥⾯⽆论是嵌套ListView还是ScrollView,滑动冲突是没有的,毕竟是官⽅的东西,可能已经考虑到了这些,所以⽐较完善。

复杂⼀点的滑动冲突,基本上就是这两个冲突结合的结果。

滑动冲突解决思路滑动冲突,就其本质来说,两个不同⽅向(或者是同⽅向)的View,其中有⼀个是占主导地位的,每次总是抢着去处理外界的滑动⾏为,这样就导致⼀种很别扭的⽤户体验,明明只是横向的滑动了⼀下,纵向的列表却在垂直⽅向发⽣了动作。

就是说,这个占主导地位的View,每⼀次都⾝不由⼰的拦截了这个滑动的动作,因此,要解决滑动冲突,就是得明确告诉这个占主导地位的View,什么时候你该拦截,什么时候你不应该拦截,应该由下⼀层的View去处理这个滑动动作。

这⾥不明⽩的同学,可以去了解⼀下Android Touch事件的分发机制,这也是解决滑动冲突的核⼼知识。

第⼆种滑动冲突,解决起来是⽐较简单的。

这⾥就结合例⼦说⼀下。

这⾥,说⼀下背景情况。

之前做下拉刷新、上拉加载更多时⼀直使⽤的是PullToRefreshView这个控件,因为很⽅便,不⽤导⼊三⽅⼯程。

在其内部可以放置ListView,GridView及ScrollView,⾮常⽅便,⽤起来可谓是屡试不爽。

android中view手势滑动冲突的解决方法

android中view手势滑动冲突的解决方法

android中view⼿势滑动冲突的解决⽅法Android⼿势事件的冲突跟点击事件的分发过程息息相关,由三个重要的⽅法来共同完成,分别是:dispatchTouchEvent、onInterceptTouchEvent和onTouchEvent。

public boolean dispatchTouchEvent(MotionEvent ev)这个⽅法⽤来进⾏事件的分发。

如果事件传递到view,那么这个⽅法⼀定会被调⽤,返回结果受当前View的onTouchEvent和下级View的dispatchTouchEvent⽅法的影响,表⽰是否消耗当前事件。

public boolean onInterceptTouchEvent(MotionEvent event)在上述⽅法内部调⽤,⽤来判断是拦截某个事件,如果当前View拦截了某个事件,那么在同⼀个事件序列当中,此⽅法不会被再次调⽤,返回结果表⽰是否拦截当前事件。

public boolean onTouchEvent(MotionEvent event)在dispathcTouchEvent⽅法中调⽤,⽤来处理点击事件,返回结果表⽰是否消耗当前事件,如果不消耗,则在同⼀个事件序列中,当前View⽆法再次接到事件。

例:public boolean dispatchTouchEvent(MotionEvent ev){boolean consume = false;if(onInterceptTouchEvent(ev)){consume = onTouchEvent(ev);} else {consum = child.dispathcTouchEvent(ev);}return consume;}⼿势冲突的解决⽅法就是⽤上⾯的三个⽅法;主要分为两种解决⽅法:·1外部拦截法 2内部拦截法1.常见的滑动冲突场景1.1 外部滑动⽅向和内部滑动的⽅向不⼀致这种情况我们经常遇见,⽐如使⽤viewpaper+listview时,在这种效果中,可以通过左右滑动切换页⾯,⽽每⼀个页⾯往往⼜是⼀个listview,本来在这种情况下是有冲突的,但是Viewpaper内部处理了这个滑动冲突,因此采⽤viewpaper我们⽆需关注这个问题,如果我们采⽤的不是Viewpaper⽽是ScrollView等,那么必须⼿动处理滑动冲突,否则内外两层只能有⼀层滑动,那就是滑动冲突。

UIGestureRecognizer手势和scrollview冲突的简单解决

UIGestureRecognizer手势和scrollview冲突的简单解决
问题:想实现一个TableView里面的cell的拉动露出编辑按钮的功能,用的是UIGestureRecognizer实现的,但是和UITableView的 UIScrollView冲突了,导致每次拉动tableView都会调用UIGestห้องสมุดไป่ตู้reRecognizer的方法。
解决方案:
- (BOOL)gestureRecognizerShouldBegin:(UIPanGestureRecognizer *)gestureRecognizer{ if ([gestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]]) { CGPoint vTranslationPoint = [gestureRecognizer translationInView:self.contentView]; return fabs(vTranslationPoint.x) > fabs(vTranslationPoint.y);//如果手势纵向移动位移比横向位移大则不响应 } return YES;
其实就是在每个cell里面添加了gesturerecognizershouldbegin的筛选条件代码中translationinview返回手势移动的位移矢量另外一个方法velocityinview返回的是手势移动的速度矢量
UIGestureRecognizer手势和 scrollview冲突的简单解决
} 其实就是在每个cell里面添加了 gestureRecognizerShouldBegin的筛选条件, 代码中translationInView返回手势移动的位移矢量,另外 一个方法velocityInView返回的是手势移动的速度矢量。其实也可以重写TableView中scrollView的相关方法,在有多个 UIGestureRecognizer的时候应该采取这种方式。

flutter singlechildscrollview listview 简书

flutter singlechildscrollview listview 简书

flutter singlechildscrollview listview 简书摘要:1.简介2.Flutter 简介3.SingleChildScrollView 组件介绍4.ListView 组件介绍5.使用SingleChildScrollView 和ListView 的实践6.总结正文:1.简介在Flutter 中,SingleChildScrollView 和ListView 是非常常用的组件,可以用来展示大量的数据。

本文将详细介绍这两个组件的使用方法以及如何结合使用它们。

2.Flutter 简介Flutter 是谷歌推出的一款开源UI 工具包,可以快速构建美观且高性能的Android 和iOS 应用程序。

Flutter 使用Dart 编程语言,并提供了丰富的组件库,使得开发者可以轻松地构建出各种复杂的界面。

3.SingleChildScrollView 组件介绍SingleChildScrollView 是一个容器组件,可以包裹一个子组件,并为其提供滚动功能。

它的主要特点是只能包含一个子组件,并且可以自动调整子组件的大小以填充整个空间。

使用SingleChildScrollView 可以使得界面更加简洁,易于维护。

4.ListView 组件介绍ListView 是一个列表组件,可以展示一系列的项目。

它支持多种列表类型,如无序列表、有序列表和网格列表等。

ListView 可以自动处理滚动事件,使得用户可以轻松地查看和操作列表中的项目。

5.使用SingleChildScrollView 和ListView 的实践假设我们要实现一个简单的聊天应用,需要展示消息列表。

我们可以使用SingleChildScrollView 来包裹ListView,使得消息列表可以滚动。

具体代码如下:```dartimport "package:flutter/material.dart";void main() {runApp(MyApp());}class MyApp extends StatelessWidget {@overrideWidget build(BuildContext context) {return MaterialApp(home: Scaffold(appBar: AppBar(title: Text("聊天应用")),body: SingleChildScrollView(child: ListView.builder(itemCount: 100,itemBuilder: (context, index) {return ListTile(title: Text("消息$index"));},),),),);}}```在这个例子中,我们使用SingleChildScrollView 来包裹ListView.builder,这样可以实现消息列表的滚动功能。

Unity实现滑页嵌套(解决ScrollRect嵌套冲突问题)

Unity实现滑页嵌套(解决ScrollRect嵌套冲突问题)

Unity实现滑页嵌套(解决ScrollRect嵌套冲突问题)简介由于项目需要+有网友咨询,所以做了个横向滑页+某一横向滑页中有竖向滑页的demo,实现有点绕弯子,但基本功能还是比较完善,发上来共享一下。

效果思路第一步的思路是自己判断触屏拖动位置,然后控制界面横向或者纵向滑动。

然后,由于UGUI组件重叠时会屏蔽事件比如Button会屏蔽掉PointerDown(PS:当然也可以采取继承UGUI组件的方式释放屏蔽事件,这里对UGUI源码不熟,采取自己写一个事件分发器方便一点)项目配置这里就不赘述咯,我的前一篇blog有详细配置说明:1.首先建立两个ScrollRect2.分别给两个ScrollRect配置格子的ScrollBar,然后关掉以下设置3.在最外层的ScrollRect配置ScrollControl代码(PS:代码后续给出)4.配置InputControl(PS:新建一个Gameobjct就可以咯,也可以挂在已有物体上)5.运行,检查效果...代码代码写的比较急,很多不规范的地方,使用者请看懂逻辑之后自行重构,直接使用者有坑勿怪InputControlusing UnityEngine;public delegate void MouseDownEvent(Vector2 mousePosition);public delegate void MouseUpEvent(Vector2 mousePosition);public delegate void MouseDragEvent(Vector2 dragVector);public delegate void MouseClickEvent(Vector2 mousePosition);public class InputControl : MonoBehaviour{private static InputControl mInstance;/// <summary>/// 逗比单例模式/// </summary>public static InputControl Instance{get{return mInstance;}}private bool isPress;private bool isClick;private bool tempPress;private Vector2 oldMousePosition;private Vector2 tempMousePosition;public event MouseDownEvent EVENT_MOUSE_DOWN; public event MouseUpEvent EVENT_MOUSE_UP; public event MouseDragEvent EVENT_MOUSE_DRAG; public event MouseClickEvent EVENT_MOUSE_CLICK;/// <summary>/// 拖动起始判断参数,可自行更改/// </summary>public const float JUDGE_DISTANCE = 1F;void Awake(){mInstance = this;//以下代码可优化EVENT_MOUSE_DOWN += AvoidEmpty; EVENT_MOUSE_UP += AvoidEmpty; EVENT_MOUSE_DRAG += AvoidEmpty; EVENT_MOUSE_CLICK += AvoidEmpty;}void Start(){isPress = false;isClick = false;}/// <summary>/// 防空保护函数,无用处,可自行优化/// </summary>/// <param name="noUse"></param> private void AvoidEmpty(Vector2 noUse) { }void Update(){tempPress = Input.GetMouseButton(0); tempMousePosition = Input.mousePosition;// 两次状态不同,触发点击和抬起事件if (tempPress != isPress){// 按下事件if (tempPress){isClick = true;EVENT_MOUSE_DOWN(tempMousePosition);}// 抬起事件else{EVENT_MOUSE_UP(tempMousePosition);// 点击事件if (isClick){EVENT_MOUSE_CLICK(tempMousePosition);}isClick = false;}}// 按下的过程中发生了移动,发生事件变化else if (isClick && JudgeMove(oldMousePosition, tempMousePosition)){isClick = false;}// 拖动事件else if (tempPress && !isClick){EVENT_MOUSE_DRAG(tempMousePosition - oldMousePosition);}isPress = tempPress;oldMousePosition = tempMousePosition;}/// <summary>/// 判断是否超出静止范围,用static速度更快/// </summary>/// <param name="p1"></param>/// <param name="p2"></param>/// <returns></returns>private static bool JudgeMove(Vector2 p1, Vector2 p2){return Mathf.Abs(p1.x - p2.x) > JUDGE_DISTANCE || Mathf.Abs(p1.y - p2.y) > JUDGE_DISTANCE;}}ScrollControlusing UnityEngine;using UnityEngine.UI;public class ScrollControl : MonoBehaviour{/// 横向滚动条/// </summary>public Scrollbar m_HScrollBar;/// <summary>/// 竖向滚动条/// </summary>public Scrollbar[] m_VScrollBars;/// <summary>/// 有竖向滚动的页面/// </summary>public int[] m_VScrollIndexs;/// <summary>/// 页面个数/// </summary>public int m_Num;/// <summary>/// 设置移动超过多少百分比之后向下翻页/// </summary>public float m_NextLimit;/// <summary>/// 滑动敏感值/// </summary>public float m_Sensitive;/// 鼠标上一次的位置/// </summary>private Vector3 mOldPosition;/// <summary>/// 记录上一次的value/// </summary>private float mOldValue;private float mTargetPosition = 0.5f; private int mCurrentIndex = 3;private int mTargetIndex = 3;/// <summary>/// 是否可以移动/// </summary>private bool mCanMove = false;/// <summary>/// 初始移动速度/// </summary>private float mMoveSpeed;/// <summary>/// 平滑移动参数/// </summary>private const float SMOOTH_TIME = 0.2F;private float mDragParam = 0;private float mPageWidth = 0;/// <summary>/// 是否需要进行滑动方向判定/// </summary>private bool mNeedCaculate = false;/// <summary>/// 是否进行竖向滚动/// </summary>private bool mIsScollV = false;/// <summary>/// 竖向临时滚动条/// </summary>private Scrollbar mVScrollBar;public void SetNextIndex(int pIndex){mTargetIndex = pIndex;mTargetPosition = (mTargetIndex - 1) * mPageWidth; mIsScollV = false;mCanMove = true;}private void OnPointerDown(Vector2 mousePosition) {// 记录当前valuemOldValue = m_HScrollBar.value;mOldPosition = Input.mousePosition;// mCanMove = false;mCurrentIndex = GetCurrentIndex(mOldValue);// 判断当前是否在可竖向滑动的页面上for (int i = 0; i < m_VScrollIndexs.Length; ++i){if (m_VScrollIndexs[i] == mCurrentIndex){mNeedCaculate = true;mVScrollBar = m_VScrollBars[i];break;}}}private void OnDrag(Vector2 mousePosition){Vector2 dragVector = Input.mousePosition - mOldPosition;if (mNeedCaculate){mNeedCaculate = false;if (Mathf.Abs(dragVector.x) > Mathf.Abs(dragVector.y)) {mIsScollV = false;}elsemIsScollV = true;}}DragScreen(dragVector);mOldPosition = Input.mousePosition;}private void OnPointerUp(Vector2 mousePosition){Vector2 dragVector = Input.mousePosition - mOldPosition; DragScreen(dragVector);mOldPosition = Input.mousePosition;float valueOffset = m_HScrollBar.value - mOldValue;if (Mathf.Abs((valueOffset) / mPageWidth) > m_NextLimit) {mTargetIndex += valueOffset > 0 ? 1 : -1; mTargetPosition = (mTargetIndex - 1) * mPageWidth;}mCanMove = true;}private int GetCurrentIndex(float pCurrentValue){return Mathf.RoundToInt(pCurrentValue / mPageWidth + 1);private void DragScreen(Vector2 pDragVector){if (mIsScollV){float oldValue = mVScrollBar.value;mVScrollBar.value -= pDragVector.y / Screen.height * mVScrollBar.size;mMoveSpeed = mVScrollBar.value - oldValue;}else{float oldValue = m_HScrollBar.value;m_HScrollBar.value -= pDragVector.x / Screen.width * mDragParam;mMoveSpeed = m_HScrollBar.value - oldValue;}}void Awake(){if (m_Num <= 1){Debug.LogError("参数错误:页面个数不对");}mDragParam = 1f / (m_Num - 1) * m_Sensitive;mPageWidth = 1f / (m_Num - 1);mCurrentIndex = GetCurrentIndex(m_HScrollBar.value);mTargetIndex = mCurrentIndex;void Start(){InputControl.Instance.EVENT_MOUSE_DOWN += OnPointerDown;InputControl.Instance.EVENT_MOUSE_UP += OnPointerUp;InputControl.Instance.EVENT_MOUSE_DRAG += OnDrag;}void OnDestory(){InputControl.Instance.EVENT_MOUSE_DOWN -= OnPointerDown;InputControl.Instance.EVENT_MOUSE_UP -= OnPointerUp;InputControl.Instance.EVENT_MOUSE_DRAG -= OnDrag;}void Update(){if (mCanMove){if (mIsScollV){mVScrollBar.value += mMoveSpeed;float absValue = Mathf.Abs(mMoveSpeed);absValue -= 0.001f;if (absValue <= 0){mCanMove = false;}else{mMoveSpeed = mMoveSpeed > 0 ? absValue : -absValue;}}else{if (Mathf.Abs(m_HScrollBar.value - mTargetPosition) < 0.01f) {m_HScrollBar.value = mTargetPosition;mCurrentIndex = mTargetIndex;mCanMove = false;return;}m_HScrollBar.value = Mathf.SmoothDamp(m_HScrollBar.value, mTargetPosition, ref mMoveSpeed, SMOOTH_TIME);}}}}总结目前来看效果还可以,两种滑动无干扰,有简单的阻尼滑动效果,滑动分页界限可以设置其他若有什么问题,欢迎留言。

项目中引用多个第三方库引发冲突的解决方案

项目中引用多个第三方库引发冲突的解决方案

项目中引用多个第三方库引发冲突的解决方案
在项目开发过程中,引用第三方库是非常常见的情况。

但有时候,不同的第三方库可能会依赖于相同的另一个库,且版本不同,从而导致冲突。

这种冲突会影响项目的正常运行,因此必须解决。

以下是一些解决方案:
1. 版本锁定
通过在项目中明确指定每个第三方库的版本号,可以避免不同库依赖不同版本的情况。

这种方式需要手动管理所有库的版本,确保它们兼容。

2. 依赖隔离
利用依赖管理工具(如Maven、Gradle等)提供的依赖隔离机制,将冲突的库隔离到不同的ClassLoader中。

这样,不同的库可以使用不同版本的依赖库,互不影响。

3. 代码重构
分析冲突的根源,尝试重构代码,将依赖冲突的部分剥离出来,单独封装成独立的模块。

这样可以让主项目不受影响,但需要付出额外的开发成本。

4. 升级或替换库
如果冲突是由于某些库版本过低或存在问题导致的,可以尝试将其升级到较新的兼容版本。

如果升级无法解决问题,也可以考虑用其他
替代库来替换。

5. 反射机制
有些情况下,可以利用反射机制在运行时动态加载需要的库版本,从而规避编译期的冲突。

但这种方式通常比较复杂,需要对代码做较大改动。

6. 源码修改
如果上述方法都无法解决问题,最后的选择是直接修改引发冲突的第三方库源码。

这种做法风险很高,需要对库源码有深入的理解,并做好向后兼容的准备。

解决第三方库冲突需要根据具体情况选择合适的方案。

通常优先考虑版本锁定、依赖隔离等无需改动代码的方式,其次是升级库或代码重构,最后才是反射或源码修改等高风险方案。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

Android之ScrollView嵌套ListView冲突.
在ScrollView中嵌套使用ListView,ListView只会显示一行多一点。

两者进行嵌套,即会发生冲突。

由于ListView本身都继承于ScrollView,一旦在ScrollView中嵌套ScrollView,
那么里面的ScrollView高度计算就会出现问题。

我们也就无法得到想要的效果。

下面进入正题,我们将讨论ScrollView中嵌套ListView情况。

核心解决方案:重写ListView或者GridView的OnMesure 方法。

对GridView同样适用。

ScrollView中嵌套ListView:
package com.android.xiaomolongstudio.example.scrollviewlistview;
import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.widget.ArrayAdapter;
import android.widget.ListView;
/**
*
* @author 小尛龙
*
*/
public class MainActivity extends Activity {
ListView listView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(yout.activity_main);
listView = (ListView) findViewById(R.id.listView);
listView.setAdapter(new ArrayAdapter<String>(this,
yout.simple_expandable_list_item_1, getData()));
}
private List<String> getData() {
List<String> data = new ArrayList<String>();
for (int i = 0; i < 30; i++) {
data.add("测试" + i);
}
return data;
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
}
自定义ListView:
package com.android.xiaomolongstudio.example.scrollviewlistview;
import android.content.Context;
import android.util.AttributeSet;
import android.widget.ListView;
public class MyListView extends ListView {
public MyListView(Context context) {
super(context);
}
public MyListView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyListView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,
MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, expandSpec);
}
}
没有上面的按钮,一进页面直接显示的是ListView内容,怎么一开始就显示头部。

ScrollView有个属性mScrollView.scrollTo(x, y)可以显示位置。

但是实际却没有达到效果,查了说mScrollView.scrollTo(x, y)首次初始化时无效果。

最后我用了mScrollView.smoothScrollTo(0,0);。

相关文档
最新文档