AmazingListView+AmazingAdapter

本文介绍了一种自定义的Android列表视图AmazingListView,该视图支持头部固定、加载更多等功能,并提供了详细的实现代码。
package com.example.XCar;

import android.content.Context;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.view.View;
import android.widget.ListAdapter;
import android.widget.ListView;

/**
 * Created with IntelliJ IDEA.
 * User: S7
 * Date: 13-7-22
 * Time: 下午8:46
 * To change this template use File | Settings | File Templates.
 */
public class AmazingListView extends ListView
        implements AmazingAdapter.HasMorePagesListener
{
    public static final String TAG = AmazingListView.class.getSimpleName();
    private AmazingAdapter adapter;
    boolean footerViewAttached = false;
    public boolean isScrolling = false;
    View listFooter;
    private View mHeaderView;
    private int mHeaderViewHeight;
    private boolean mHeaderViewVisible;
    private int mHeaderViewWidth;
    public AmazingListViewScrollListener my_scrolling_listener;

    public AmazingListView(Context paramContext)
    {
        super(paramContext);
    }

    public AmazingListView(Context paramContext, AttributeSet paramAttributeSet)
    {
        super(paramContext, paramAttributeSet);
    }

    public AmazingListView(Context paramContext, AttributeSet paramAttributeSet, int paramInt)
    {
        super(paramContext, paramAttributeSet, paramInt);
    }

    public void configureHeaderView(int position)
    {
        if(this.mHeaderView == null){
            return;
        }

        int state = adapter.getPinnedHeaderState(position);

        switch (state){
            case AmazingAdapter.PINNED_HEADER_GONE:

                mHeaderViewVisible = false;
                break;
            case AmazingAdapter.PINNED_HEADER_VISIBLE:
                adapter.configurePinnedHeader(mHeaderView, position, 255);
                if (mHeaderView.getTop() != 0) {
                    mHeaderView.layout(0, 0, mHeaderViewWidth, mHeaderViewHeight);
                }
                mHeaderViewVisible = true;
                break;


            case AmazingAdapter.PINNED_HEADER_PUSHED_UP:
                View firstView = getChildAt(0);
                if (firstView != null) {
                    int bottom = firstView.getBottom();
                    int headerHeight = mHeaderView.getHeight();
                    int y;
                    int alpha;
                    if (bottom < headerHeight) {
                        y = (bottom - headerHeight);
                        alpha = 255 * (headerHeight + y) / headerHeight;
                    } else {
                        y = 0;
                        alpha = 255;
                    }
                    adapter.configurePinnedHeader(mHeaderView, position, alpha);
                    if (mHeaderView.getTop() != y) {
                        mHeaderView.layout(0, y, mHeaderViewWidth, mHeaderViewHeight + y);
                    }
                    mHeaderViewVisible = true;
                }
                break;

        }
    }

    protected void dispatchDraw(Canvas canvas)
    {
        super.dispatchDraw(canvas);
        if (mHeaderViewVisible)
            drawChild(canvas, mHeaderView, getDrawingTime());
    }

    public AmazingAdapter getAdapter()
    {
        return this.adapter;
    }

    public View getLoadingView()
    {
        return this.listFooter;
    }

    public boolean isLoadingViewVisible()
    {
        return this.footerViewAttached;
    }

    public void mayHaveMorePages()
    {
        if (! footerViewAttached && listFooter != null) {
            this.addFooterView(listFooter);
            footerViewAttached = true;
        }
    }

    public void noMorePages()
    {
        if (this.listFooter != null)
            removeFooterView(this.listFooter);
        this.footerViewAttached = false;
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
        if (mHeaderView != null) {
            mHeaderView.layout(0, 0, mHeaderViewWidth, mHeaderViewHeight);
            configureHeaderView(getFirstVisiblePosition());
        }
    }


    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        if (mHeaderView != null) {
            measureChild(mHeaderView, widthMeasureSpec, heightMeasureSpec);
            mHeaderViewWidth = mHeaderView.getMeasuredWidth();
            mHeaderViewHeight = mHeaderView.getMeasuredHeight();
        }
    }

    public void setAdapter(ListAdapter paramListAdapter)
    {
        if (!(paramListAdapter instanceof AmazingAdapter))
            throw new IllegalArgumentException(AmazingListView.class.getSimpleName() + " must use adapter of type " + AmazingAdapter.class.getSimpleName());
        if (this.adapter != null)
        {
            this.adapter.setHasMorePagesListener(null);
            setOnScrollListener(null);
        }
        this.adapter = ((AmazingAdapter)paramListAdapter);
        ((AmazingAdapter)paramListAdapter).setHasMorePagesListener(this);
        setOnScrollListener((AmazingAdapter)paramListAdapter);
        View localView = new View(getContext());
        super.addFooterView(localView);
        super.setAdapter(paramListAdapter);
        super.removeFooterView(localView);
        requestLayout();
    }

    public void setLoadingView(View paramView)
    {
        this.listFooter = paramView;
    }

    public void setPinnedHeaderView(View paramView)
    {
        this.mHeaderView = paramView;
        if (this.mHeaderView != null)
            setFadingEdgeLength(0);
        requestLayout();
    }

    public void setPinnedHeaderViewHeight(int paramInt)
    {
        this.mHeaderViewHeight = paramInt;
    }

    public void setScrollingListener(AmazingListViewScrollListener paramAmazingListViewScrollListener)
    {
        this.my_scrolling_listener = paramAmazingListViewScrollListener;
    }
}
package com.example.XCar;

import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.BaseAdapter;
import android.widget.SectionIndexer;

/**
 * Created with IntelliJ IDEA.
 * User: S7
 * Date: 13-7-22
 * Time: 下午8:47
 * To change this template use File | Settings | File Templates.
 */
public abstract class AmazingAdapter extends BaseAdapter
        implements SectionIndexer, AbsListView.OnScrollListener
{
    public static final int PINNED_HEADER_GONE = 0;
    public static final int PINNED_HEADER_PUSHED_UP = 2;
    public static final int PINNED_HEADER_VISIBLE = 1;
    public static final String TAG = AmazingAdapter.class.getSimpleName();
    boolean automaticNextPageLoading = false;
    HasMorePagesListener hasMorePagesListener;
    int initialPage = 1;
    int page = 1;

    protected abstract void bindSectionHeader(View paramView, int paramInt, boolean paramBoolean);

    public abstract void configurePinnedHeader(View paramView, int paramInt1, int paramInt2);

    public abstract View getAmazingView(int paramInt, View paramView, ViewGroup paramViewGroup);

    /**
     * Computes the desired state of the pinned header for the given
     * position of the first visible list item. Allowed return values are
     * {@link #PINNED_HEADER_GONE}, {@link #PINNED_HEADER_VISIBLE} or
     * {@link #PINNED_HEADER_PUSHED_UP}.
     */
    public int getPinnedHeaderState(int position) {
        if (position < 0 || getCount() == 0) {
            return PINNED_HEADER_GONE;
        }

        // The header should get pushed up if the top item shown
        // is the last item in a section for a particular letter.
        int section = getSectionForPosition(position);
        int nextSectionPosition = getPositionForSection(section + 1);
        if (nextSectionPosition != -1 && position == nextSectionPosition - 1) {
            return PINNED_HEADER_PUSHED_UP;
        }

        return PINNED_HEADER_VISIBLE;
    }

    public abstract int getPositionForSection(int paramInt);

    public abstract int getSectionForPosition(int paramInt);

    public abstract Object[] getSections();

    public final View getView(int position, View convertView, ViewGroup parent)
    {
       /* View localView = getAmazingView(paramInt, paramView, paramViewGroup);
        if ((paramInt == -1 + getCount()) && (this.automaticNextPageLoading))
            onNextPageRequested(1 + this.page);
        if (getPositionForSection(getSectionForPosition(paramInt)) == paramInt);
        for (boolean bool = true; ; bool = false)
        {
            bindSectionHeader(localView, paramInt, bool);
            return localView;
        }*/

        View res = getAmazingView(position, convertView, parent);

        if (position == getCount() - 1 && automaticNextPageLoading) {
            onNextPageRequested(page + 1);
        }

        final int section = getSectionForPosition(position);
        boolean displaySectionHeaders = (getPositionForSection(section) == position);

        bindSectionHeader(res, position, displaySectionHeaders);

        return res;
    }

    public void nextPage()
    {
        this.page = (1 + this.page);
    }

    public void notifyMayHaveMorePages()
    {
        this.automaticNextPageLoading = true;
        if (this.hasMorePagesListener != null)
         this.hasMorePagesListener.mayHaveMorePages();
    }

    public void notifyNoMorePages()
    {
        this.automaticNextPageLoading = false;
        if (this.hasMorePagesListener == null)
            return;
        this.hasMorePagesListener.noMorePages();
    }

    protected abstract void onNextPageRequested(int paramInt);

    public void onScroll(AbsListView paramAbsListView, int paramInt1, int paramInt2, int paramInt3)
    {
        if (paramAbsListView instanceof AmazingListView)
             ((AmazingListView)paramAbsListView).configureHeaderView(paramInt1);
    }

    public void onScrollStateChanged(AbsListView view, int scrollState)
    {
        if(view instanceof AmazingListView){
            if(scrollState != PINNED_HEADER_GONE){
                ((AmazingListView)view).isScrolling = true;
            }else{
                ((AmazingListView)view).isScrolling = false;
            }
        }

        if(((AmazingListView)view).my_scrolling_listener != null)
            ((AmazingListView)view).my_scrolling_listener.isScrolling();


       /* if (paramAbsListView instanceof AmazingListView)
        {
            if (paramInt != 0)
                break label20;
            ((AmazingListView)paramAbsListView).isScrolling = false;
        }
        do
        {
            return;
            label20: ((AmazingListView)paramAbsListView).isScrolling = true;
        }
        while (((AmazingListView)paramAbsListView).my_scrolling_listener == null);
        ((AmazingListView)paramAbsListView).my_scrolling_listener.isScrolling();*/
    }

    public void resetPage()
    {
        this.page = this.initialPage;
    }

    void setHasMorePagesListener(HasMorePagesListener paramHasMorePagesListener)
    {
        this.hasMorePagesListener = paramHasMorePagesListener;
    }

    public void setInitialPage(int paramInt)
    {
        this.initialPage = paramInt;
    }

    public static abstract interface HasMorePagesListener
    {
        public abstract void mayHaveMorePages();

        public abstract void noMorePages();
    }
}


内容概要:本文介绍了一套针对智能穿戴设备的跑步/骑行轨迹记录系统实战方案,旨在解决传统运动APP存在的定位漂移、数据断层和路径分析单一等问题。系统基于北斗+GPS双模定位、惯性测量单元(IMU)和海拔传感器,实现高精度轨迹采集,并通过卡尔曼滤波算法修正定位误差,在信号弱环境下利用惯性导航补位,确保轨迹连续性。系统支持跑步与骑行两种场景的差异化功能,包括实时轨迹记录、多维度路径分析(如配速、坡度、能耗)、数据可视化(地图标注、曲线图、3D回放)、异常提醒及智能优化建议,并可通过蓝牙/Wi-Fi同步数据至手机APP,支持社交分享与专业软件导出。技术架构涵盖硬件层、设备端与手机端软件层以及云端数据存储,强调低功耗设计与用户体验优化。经过实测验证,系统在定位精度、续航能力和场景识别准确率方面均达到预期指标,具备良好的实用性和扩展性。; 适合人群:具备一定嵌入式开发或移动应用开发经验,熟悉物联网、传感器融合与数据可视化的技术人员,尤其是从事智能穿戴设备、运动健康类产品研发的工程师和产品经理;也适合高校相关专业学生作为项目实践参考。; 使用场景及目标:① 开发高精度运动轨迹记录功能,解决GPS漂移与断点问题;② 实现跑步与骑行场景下的差异化数据分析与个性化反馈;③ 构建完整的“终端采集-手机展示-云端存储”系统闭环,支持社交互动与商业拓展;④ 掌握低功耗优化、多源数据融合、动态功耗调节等关键技术在穿戴设备中的落地应用。; 阅读建议:此资源以真实项目为导向,不仅提供详细的技术实现路径,还包含硬件选型、测试验证与商业扩展思路,建议读者结合自身开发环境,逐步实现各模块功能,重点关注定位优化算法、功耗控制策略与跨平台数据同步机制的设计与调优。
内容概要:《QTools_V4.6.1用户手册》详细介绍了一款专为AutoCAD及CASS设计的辅助插件,涵盖测绘、设计等多个领域,提供超过400项实用功能。主要包括拓扑检查(如碎线、碎面、短边、弧段、锐角等检查)、图形与文字处理工具(如批量插图、文字对齐、编号、合并、替换等)、测绘专用工具(如断面、高程点、等高线、三角网处理)、以及图纸管理功能(如拆分、合并、解密、批量修改)等。插件支持云授权和加密锁两种激活方式,兼容AutoCAD 2004–2026及各版本CASS,并提供侧边栏、菜单栏、自定义命令等多种操作方式,同时具备自动更新与性能检测功能。; 适合人群:从事测绘、地理信息、建筑设计等相关领域的技术人员,熟悉AutoCAD/CASS操作,具备一定工程制图经验的从业人员。; 使用场景及目标:①用于地形图、地籍图、宗地图等专业图纸的自动化处理与质量检查;②提升CAD绘图效率,实现批量操作、数据提取、格式转换、拓扑修复等任务;③支持测绘项目中的断面绘制、高程分析、坐标展点、土方计算等核心流程;④解决图纸编辑受限、字体缺失、块无法分解等问题。; 阅读建议:建议结合实际项目操作手册中的功能命令,优先掌握常用快捷指令(如qq、tp、dm、gcd等),并利用“功能搜索”快速定位工具。使用前确保正确加载插件并完成授权,遇到问题可参考“常见问题”章节进行排查。定期关注更新内容以获取新功能和优化体验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值