当前位置: 首页 > wzjs >正文

品牌网站建设的作用网站做线

品牌网站建设的作用,网站做线,网站开发主要流程,商城型网站开发网站建设在 Android 中实现自定义 View 处理 1 万条数据的流畅滑动,需结合视图复用、按需绘制、硬件加速等核心技术。以下是具体实现方案: 一、核心优化策略 1. 视图复用机制(类似 RecyclerView) ViewHolder 模式:将每个数据…

在 Android 中实现自定义 View 处理 1 万条数据的流畅滑动,需结合视图复用、按需绘制、硬件加速等核心技术。以下是具体实现方案:

一、核心优化策略

1. 视图复用机制(类似 RecyclerView)
  • ViewHolder 模式:将每个数据项的视图封装为 ViewHolder,通过对象池复用视图实例。
class ItemViewHolder {View itemView;TextView textView;// 其他子控件
}

对象池管理:使用LinkedList<ItemViewHolder>缓存闲置视图,避免频繁创建销毁

private final LinkedList<ItemViewHolder> viewPool = new LinkedList<>();private ItemViewHolder obtainViewHolder() {if (viewPool.isEmpty()) {View itemView = LayoutInflater.from(context).inflate(R.layout.item_layout, this, false);return new ItemViewHolder(itemView);}return viewPool.poll();
}private void recycleViewHolder(ItemViewHolder holder) {viewPool.offer(holder);
}
2. 按需绘制(仅渲染可见区域)
  • 计算可见范围:根据滚动偏移量(scrollY)和视图高度,确定需绘制的起始和结束索引。
@Override
protected void onDraw(Canvas canvas) {super.onDraw(canvas);int visibleStart = (int) Math.floor(scrollY / itemHeight);int visibleEnd = (int) Math.ceil((scrollY + getHeight()) / itemHeight);for (int i = visibleStart; i <= visibleEnd; i++) {if (i >= dataList.size()) break;drawItem(canvas, i);}
}

3. 硬件加速与缓存优化
  • 启用硬件加速:在构造函数中设置setLayerType(LAYER_TYPE_HARDWARE, null)
  • 缓存绘制结果:使用Bitmap缓存已绘制的视图区域,减少重复计算。
private Bitmap cacheBitmap;
private Canvas cacheCanvas;@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {super.onSizeChanged(w, h, oldw, oldh);cacheBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);cacheCanvas = new Canvas(cacheBitmap);
}@Override
protected void onDraw(Canvas canvas) {// 先绘制到缓存画布,再整体绘制到屏幕cacheCanvas.drawColor(Color.WHITE);// 绘制可见项canvas.drawBitmap(cacheBitmap, 0, 0, null);
}

二、实现步骤

1. 数据适配器设计
  • 抽象数据适配器:分离数据逻辑与视图渲染。
public abstract class DataAdapter<T> {public abstract int getItemCount();public abstract T getItem(int position);public abstract int getItemHeight(int position);public abstract void bindViewHolder(ItemViewHolder holder, T item);
}
2. 触摸事件处理
  • 惯性滚动实现:使用ScrollerVelocityTracker
private Scroller scroller;
private VelocityTracker velocityTracker;@Override
public boolean onTouchEvent(MotionEvent event) {if (velocityTracker == null) {velocityTracker = VelocityTracker.obtain();}velocityTracker.addMovement(event);switch (event.getAction()) {case MotionEvent.ACTION_DOWN:if (!scroller.isFinished()) {scroller.abortAnimation();}startY = (int) event.getY();break;case MotionEvent.ACTION_MOVE:int dy = (int) (event.getY() - startY);scrollBy(0, -dy);startY = (int) event.getY();break;case MotionEvent.ACTION_UP:velocityTracker.computeCurrentVelocity(1000);int velocityY = (int) velocityTracker.getYVelocity();scroller.fling(0, getScrollY(), 0, -velocityY, 0, 0, 0, maxScrollY);velocityTracker.recycle();velocityTracker = null;invalidate();break;}return true;
}@Override
public void computeScroll() {if (scroller.computeScrollOffset()) {scrollTo(scroller.getCurrX(), scroller.getCurrY());invalidate();}
}

三、性能监控与调优

1. 帧率监控
  • 使用 Android Profiler:监控 GPU 渲染帧率,确保稳定在 60fps。
  • 自定义帧率统计
private long frameTime = System.currentTimeMillis();
private int frameCount = 0;@Override
protected void onDraw(Canvas canvas) {super.onDraw(canvas);frameCount++;if (System.currentTimeMillis() - frameTime >= 1000) {Log.d(TAG, "FPS: " + frameCount);frameCount = 0;frameTime = System.currentTimeMillis();}
}
2. 内存分析
  • 使用 MAT 工具:分析内存快照,识别潜在泄漏点。
  • 资源释放:在onDetachedFromWindow中清理缓存。
@Override
protected void onDetachedFromWindow() {super.onDetachedFromWindow();if (cacheBitmap != null && !cacheBitmap.isRecycled()) {cacheBitmap.recycle();cacheBitmap = null;}
}

四、完整代码示例

public class CustomListView extends ViewGroup {private DataAdapter<?> adapter;private int itemHeight = 100; // 每项高度private int maxScrollY;// 初始化代码public CustomListView(Context context) {super(context);init();}private void init() {scroller = new Scroller(context);setWillNotDraw(false);setLayerType(LAYER_TYPE_HARDWARE, null);}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {int width = MeasureSpec.getSize(widthMeasureSpec);int height = MeasureSpec.getSize(heightMeasureSpec);setMeasuredDimension(width, height);maxScrollY = adapter.getItemCount() * itemHeight - height;}@Overrideprotected void onLayout(boolean changed, int l, int t, int r, int b) {// 布局逻辑(此处简化)}private void drawItem(Canvas canvas, int position) {ItemViewHolder holder = obtainViewHolder();adapter.bindViewHolder(holder, adapter.getItem(position));holder.itemView.layout(0, position * itemHeight - scrollY, getWidth(), (position + 1) * itemHeight - scrollY);holder.itemView.draw(canvas);recycleViewHolder(holder);}// 设置适配器public void setAdapter(DataAdapter<?> adapter) {this.adapter = adapter;requestLayout();invalidate();}
}

五、扩展建议

  1. 数据分批加载:结合分页加载,每次仅加载当前可见区域附近的数据。
  2. 预取优化:在滚动时预加载下一页数据。
  3. 动态高度支持:在DataAdapter中实现getItemHeight(int position)动态返回项高度。
  4. 缓存策略:使用 LruCache 缓存常用视图,提升复用效率。

在 Android 开发中,事件分发机制是实现用户交互的核心逻辑之一。理解事件如何被 View 接收和处理,对于解决滑动冲突、触摸响应异常等问题至关重要。以下是事件分发机制的详细解析:

一、事件分发的核心流程

事件分发遵循Activity → ViewGroup → View的传递路径,通过三个关键方法实现:

  1. dispatchTouchEvent(MotionEvent ev)

    • 作用:决定事件是否继续分发。
    • 返回值:
      • true:事件由当前 View 处理,停止向下传递。
      • false:事件回传给父 View 的onTouchEvent
      • super.dispatchTouchEvent(ev):继续调用子 View 的dispatchTouchEvent
  2. onInterceptTouchEvent(MotionEvent ev)(仅 ViewGroup 可用)

    • 作用:判断是否拦截事件。
    • 返回值:
      • true:拦截事件,事件由当前 ViewGroup 处理。
      • false:不拦截,事件继续传递给子 View。
  3. onTouchEvent(MotionEvent ev)

    • 作用:处理具体的触摸事件。
    • 返回值:
      • true:事件被消费,停止向上传递。
      • false:事件未被消费,回传给父 View 的onTouchEvent

二、事件传递的典型场景

场景 1:事件被 ViewGroup 拦截
public class CustomViewGroup extends LinearLayout {@Overridepublic boolean onInterceptTouchEvent(MotionEvent ev) {// 拦截DOWN事件,后续事件(MOVE/UP)也会被拦截return ev.getAction() == MotionEvent.ACTION_DOWN;}@Overridepublic boolean onTouchEvent(MotionEvent event) {// 处理点击事件return true;}
}
场景 2:子 View 处理事件
public class CustomButton extends AppCompatButton {@Overridepublic boolean onTouchEvent(MotionEvent event) {// 处理点击事件return true;}
}

三、常见问题与解决方案

问题 1:父 View 拦截导致子 View 无法响应
  • 原因:父 ViewGroup 在onInterceptTouchEvent中错误拦截事件。
  • 解决方案
    onInterceptTouchEvent中根据业务逻辑选择性拦截(如仅拦截滑动事件)。
问题 2:事件未被消费导致冒泡
  • 原因:View 的onTouchEvent返回false,事件向上传递。
  • 解决方案
    onTouchEvent中处理完事件后返回true,或设置clickable="true"(默认消费事件)。
问题 3:滑动冲突(如嵌套滑动)
  • 解决方案
    1. 使用NestedScrollViewRecyclerView等支持嵌套滑动的控件。
    2. 重写父 ViewGroup 的onInterceptTouchEvent,根据滑动方向动态决定是否拦截。

四、优化事件分发的建议

  1. 减少层级嵌套:避免多层 ViewGroup 嵌套导致事件传递效率低下。
  2. 复用事件对象:通过MotionEvent.obtain()减少对象创建开销。
  3. 延迟处理复杂逻辑:在ACTION_UP事件中处理耗时操作,避免阻塞主线程。
  4. 使用GestureDetector:简化手势处理逻辑,如双击、长按等。

五、总结

事件分发机制的核心原则是:事件由父容器向下传递,子 View 可通过返回true消费事件。掌握这一机制能有效解决触摸响应问题,尤其在处理自定义 View 和复杂布局时更为关键。结合具体场景合理设计拦截逻辑,可显著提升用户交互体验。

感谢观看!!!

http://www.dtcms.com/wzjs/594122.html

相关文章:

  • 芜湖做网站找哪家好怎么自己网站搜不到了
  • 网络公司网站报价方案wordpress文章类插件
  • 公司建设个网站一点空间网站建设
  • 百度公司网站制作个人网站制作 教程
  • 网站备案后可以更换域名吗做网站互联网公司有哪些
  • 中装建设官方网站网站的建设 想法
  • 口碑好的专业网站建设运城姚孟网站建设
  • 网站被封了怎么办设计学习网站
  • 微餐饮网站建设比较好网站建设服务便宜
  • 长沙网页制作设计长春seo网站排名
  • 福建省新特建设工程有限公司网站网站建设主要包括哪两个方面
  • 互联网公司排名情况免费网站优化怎么做
  • 那个网站科四做课时企业网站推广怎么做
  • 湖北疾控最新提醒南京网站关键词优化
  • 中国建筑业协会官方网站检测网站为什么打不开了
  • 西安晨曦e动网站建设在线咨询24小时免费咨询
  • dedecms网站后台管理沈阳网站制作 600元
  • 怎么做导航网站网站开发学习视频
  • 黑龙江省城乡和住房建设厅网站做网站租什么服务器
  • 企业网企业网站制作我市精神文明建设的门户网站
  • 网站上的超链接怎么做wordpress 百度广告插件
  • 建站网站哪个最好wordpress夜间模式插件
  • 浙江网站建设实验心得北京网站制作设计公司排名
  • 浙江省建设厅官方网站苏州建设工程检测协会网站
  • 桐庐县网站建设药材公司网站建设模板
  • 哪些网站做外链好做网站花多少钱
  • wordpress 本地建站教程大连电子商务网站建设
  • 成品网站源码的优化技巧济南网站建设山东聚搜网咨询
  • 注册一个做网站的公司好wordpress 图库主题
  • 昆山网站建设犀牛大叔厦门中信网站