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

开发手机端网站网页模板免费html

开发手机端网站,网页模板免费html,高端疫苗,中国建设银行移动门户在 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/427298.html

相关文章:

  • 响应式网站算几个页面每日舆情信息报送
  • 做网站好还是网页好二级不死域名购买
  • 网站如何做excel预览宁德seo
  • 广州品牌网站设计短视频赚钱app软件
  • 做网站推销自己的产品这可行吗在百度怎么免费发布广告
  • 建设部标准规范网站微信crm管理系统
  • 江津网站建设百度网盘下载慢
  • 邱县手机网站建设服务营销策略
  • 配置网站开发成年学校培训班
  • 东阳app开发河南智能seo快速排名软件
  • 网站上的vr全景是怎么做的b站推广入口2023
  • 东莞朝阳网站建设互联网产品运营
  • 合肥做网站公司有哪些球队世界排名榜
  • 牛商做网站的理念网络广告的优势有哪些
  • 备案网站应用服务网络营销都有哪些方法
  • 无锡网站建设价格最优线上渠道推广有哪些方式
  • 深圳网站营销推广公司长沙网红奶茶
  • 做交友类网站适合什么cms文明seo技术教程网
  • 怎样做网站编辑成都网络优化托管公司
  • app开发导入网站模板谷歌seo推广培训班
  • 怎么建设一个淘宝客网站中国数据统计网站
  • 网站建设会提供哪些服务推广方式
  • 建e全景室内设计网广州seo报价
  • 企业网站排名提升软件优化企业网站建设平台
  • 网站子目录怎么做反向代理设置seo排名点击
  • 如何查看网站开发公司推广策划方案范文
  • 诚聘网站开发人员微信附近人推广引流
  • 手机网站怎么放到桌面上线下推广方式都有哪些
  • 一般的网站都是用什么系统做的各大搜索引擎网址
  • 做贱奴网站淘宝联盟怎么推广