XListView-View页面Copy的代码

XListView

public class XListView extends ListView implements OnScrollListener {

private float mLastY = -1; // save event y
private Scroller mScroller; // used for scroll back
private OnScrollListener mScrollListener; // user's scroll listener

// the interface to trigger refresh and load more.
private IXListViewListener mListViewListener;
// -- header view
private XListViewHeader mHeaderView;
// header view content, use it to calculate the Header's height. And hide it
// when disable pull refresh.
private RelativeLayout mHeaderViewContent;
private TextView mHeaderTimeView;
private int mHeaderViewHeight; // header view's height
private boolean mEnablePullRefresh = true;
private boolean mPullRefreshing = false; // is refreashing.

// -- footer view
private XListViewFooter mFooterView;
private boolean mEnablePullLoad;
private boolean mPullLoading;
private boolean mIsFooterReady = false;

// total list items, used to detect is at the bottom of listview.
private int mTotalItemCount;

// for mScroller, scroll back from header or footer.
private int mScrollBack;
private final static int SCROLLBACK_HEADER = 0;
private final static int SCROLLBACK_FOOTER = 1;

private final static int SCROLL_DURATION = 400; // scroll back duration
private final static int PULL_LOAD_MORE_DELTA = 50; // when pull up >= 50px
                                                    // at bottom, trigger
                                                    // load more.
private final static float OFFSET_RADIO = 1.8f; // support iOS like pull
                                                // feature.

/**
 * @param context
 */
public XListView(Context context) {
    super(context);
    initWithContext(context);
}

public XListView(Context context, AttributeSet attrs) {
    super(context, attrs);
    initWithContext(context);
}

public XListView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    initWithContext(context);
}

private void initWithContext(Context context) {
    mScroller = new Scroller(context, new DecelerateInterpolator());
    // XListView need the scroll event, and it will dispatch the event to
    // user's listener (as a proxy).
    super.setOnScrollListener(this);

    // init header view
    mHeaderView = new XListViewHeader(context);
    mHeaderViewContent = (RelativeLayout) mHeaderView
            .findViewById(R.id.xlistview_header_content);
    mHeaderTimeView = (TextView) mHeaderView
            .findViewById(R.id.xlistview_header_time);
    addHeaderView(mHeaderView);

    // init footer view
    mFooterView = new XListViewFooter(context);

    // init header height
    mHeaderView.getViewTreeObserver().addOnGlobalLayoutListener(
            new OnGlobalLayoutListener() {
                @Override
                public void onGlobalLayout() {
                    mHeaderViewHeight = mHeaderViewContent.getHeight();
                    getViewTreeObserver()
                            .removeGlobalOnLayoutListener(this);
                }
            });
}

@Override
public void setAdapter(ListAdapter adapter) {
    // make sure XListViewFooter is the last footer view, and only add once.
    if (mIsFooterReady == false) {
        mIsFooterReady = true;
        addFooterView(mFooterView);
    }
    super.setAdapter(adapter);
}

/**
 * enable or disable pull down refresh feature.
 * 
 * @param enable
 */
public void setPullRefreshEnable(boolean enable) {
    mEnablePullRefresh = enable;
    if (!mEnablePullRefresh) { // disable, hide the content
        mHeaderViewContent.setVisibility(View.INVISIBLE);
    } else {
        mHeaderViewContent.setVisibility(View.VISIBLE);
    }
}

/**
 * enable or disable pull up load more feature.
 * 
 * @param enable
 */
public void setPullLoadEnable(boolean enable) {
    mEnablePullLoad = enable;
    if (!mEnablePullLoad) {
        mFooterView.hide();
        mFooterView.setOnClickListener(null);
        // make sure "pull up" don't show a line in bottom when listview
        // with one page
        setFooterDividersEnabled(false);
    } else {
        mPullLoading = false;
        mFooterView.show();
        mFooterView.setState(XListViewFooter.STATE_NORMAL);
        // make sure "pull up" don't show a line in bottom when listview
        // with one page
        setFooterDividersEnabled(true);
        // both "pull up" and "click" will invoke load more.
        mFooterView.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                startLoadMore();
            }
        });
    }
}

/**
 * stop refresh, reset header view.
 */
public void stopRefresh() {
    if (mPullRefreshing == true) {
        mPullRefreshing = false;
        resetHeaderHeight();
    }
}

/**
 * stop load more, reset footer view.
 */
public void stopLoadMore() {
    if (mPullLoading == true) {
        mPullLoading = false;
        mFooterView.setState(XListViewFooter.STATE_NORMAL);
    }
}

/**
 * set last refresh time
 * 
 * @param time
 */
public void setRefreshTime(String time) {
    mHeaderTimeView.setText(time);
}

private void invokeOnScrolling() {
    if (mScrollListener instanceof OnXScrollListener) {
        OnXScrollListener l = (OnXScrollListener) mScrollListener;
        l.onXScrolling(this);
    }
}

private void updateHeaderHeight(float delta) {
    mHeaderView.setVisiableHeight((int) delta
            + mHeaderView.getVisiableHeight());
    if (mEnablePullRefresh && !mPullRefreshing) { // 未处于刷新状态,更新箭头
        if (mHeaderView.getVisiableHeight() > mHeaderViewHeight) {
            mHeaderView.setState(XListViewHeader.STATE_READY);
        } else {
            mHeaderView.setState(XListViewHeader.STATE_NORMAL);
        }
    }
    setSelection(0); // scroll to top each time
}

/**
 * reset header view's height.
 */
private void resetHeaderHeight() {
    int height = mHeaderView.getVisiableHeight();
    if (height == 0) // not visible.
        return;
    // refreshing and header isn't shown fully. do nothing.
    if (mPullRefreshing && height <= mHeaderViewHeight) {
        return;
    }
    int finalHeight = 0; // default: scroll back to dismiss header.
    // is refreshing, just scroll back to show all the header.
    if (mPullRefreshing && height > mHeaderViewHeight) {
        finalHeight = mHeaderViewHeight;
    }
    mScrollBack = SCROLLBACK_HEADER;
    mScroller.startScroll(0, height, 0, finalHeight - height,
            SCROLL_DURATION);
    // trigger computeScroll
    invalidate();
}

private void updateFooterHeight(float delta) {
    int height = mFooterView.getBottomMargin() + (int) delta;
    if (mEnablePullLoad && !mPullLoading) {
        if (height > PULL_LOAD_MORE_DELTA) { // height enough to invoke load
            mFooterView.setState(XListViewFooter.STATE_READY);
        } else {
            mFooterView.setState(XListViewFooter.STATE_NORMAL);
        }
    }
    mFooterView.setBottomMargin(height);

    // setSelection(mTotalItemCount - 1); // scroll to bottom
}

private void resetFooterHeight() {
    int bottomMargin = mFooterView.getBottomMargin();
    if (bottomMargin > 0) {
        mScrollBack = SCROLLBACK_FOOTER;
        mScroller.startScroll(0, bottomMargin, 0, -bottomMargin,
                SCROLL_DURATION);
        invalidate();
    }
}

private void startLoadMore() {
    mPullLoading = true;
    mFooterView.setState(XListViewFooter.STATE_LOADING);
    if (mListViewListener != null) {
        mListViewListener.onLoadMore();
    }
}

@Override
public boolean onTouchEvent(MotionEvent ev) {
    if (mLastY == -1) {
        mLastY = ev.getRawY();
    }
    switch (ev.getAction()) {
    case MotionEvent.ACTION_DOWN:
        mLastY = ev.getRawY();
        break;
    case MotionEvent.ACTION_MOVE:
        final float deltaY = ev.getRawY() - mLastY;
        mLastY = ev.getRawY();
        if (getFirstVisiblePosition() == 0
                && (mHeaderView.getVisiableHeight() > 0 || deltaY > 0)) {
            // the first item is showing, header has shown or pull down.
            updateHeaderHeight(deltaY / OFFSET_RADIO);
            invokeOnScrolling();
        } else if (getLastVisiblePosition() == mTotalItemCount - 1
                && (mFooterView.getBottomMargin() > 0 || deltaY < 0)) {
            // last item, already pulled up or want to pull up.
            updateFooterHeight(-deltaY / OFFSET_RADIO);
        }
        break;
    case MotionEvent.ACTION_CANCEL:
    case MotionEvent.ACTION_UP:
        mLastY = -1; // reset
        if (getFirstVisiblePosition() == 0) {
            // invoke refresh
            if (mEnablePullRefresh
                    && mHeaderView.getVisiableHeight() > mHeaderViewHeight) {
                mPullRefreshing = true;
                mHeaderView.setState(XListViewHeader.STATE_REFRESHING);
                if (mListViewListener != null) {
                    mListViewListener.onRefresh();
                }
            }
            resetHeaderHeight();

        } else if (getLastVisiblePosition() == mTotalItemCount - 1) {
            // invoke load more.
            if (mEnablePullLoad
                    && mFooterView.getBottomMargin() > PULL_LOAD_MORE_DELTA
                    && !mPullLoading) {
                startLoadMore();
            }
            resetFooterHeight();
        }
        break;
    }
    return super.onTouchEvent(ev);
}

@Override
public void computeScroll() {
    if (mScroller.computeScrollOffset()) {
        if (mScrollBack == SCROLLBACK_HEADER) {
            mHeaderView.setVisiableHeight(mScroller.getCurrY());
        } else {
            mFooterView.setBottomMargin(mScroller.getCurrY());
        }
        postInvalidate();
        invokeOnScrolling();
    }
    super.computeScroll();
}

@Override
public void setOnScrollListener(OnScrollListener l) {
    mScrollListener = l;
}

@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
    if (mScrollListener != null) {
        mScrollListener.onScrollStateChanged(view, scrollState);
    }
}

@Override
public void onScroll(AbsListView view, int firstVisibleItem,
        int visibleItemCount, int totalItemCount) {
    // send to user's listener
    mTotalItemCount = totalItemCount;
    if (mScrollListener != null) {
        mScrollListener.onScroll(view, firstVisibleItem, visibleItemCount,
                totalItemCount);
    }
}

public void setXListViewListener(IXListViewListener l) {
    mListViewListener = l;
}

/**
 * you can listen ListView.OnScrollListener or this one. it will invoke
 * onXScrolling when header/footer scroll back.
 */
public interface OnXScrollListener extends OnScrollListener {
    public void onXScrolling(View view);
}

/**
 * implements this interface to get refresh/load more event.
 */
public interface IXListViewListener {
    public void onRefresh();

    public void onLoadMore();
}

}

XListViewHeader

public class XListViewFooter extends LinearLayout {
public final static int STATE_NORMAL = 0;
public final static int STATE_READY = 1;
public final static int STATE_LOADING = 2;

private Context mContext;

private View mContentView;
private View mProgressBar;
private TextView mHintView;

public XListViewFooter(Context context) {
    super(context);
    initView(context);
}

public XListViewFooter(Context context, AttributeSet attrs) {
    super(context, attrs);
    initView(context);
}


public void setState(int state) {
    mHintView.setVisibility(View.INVISIBLE);
    mProgressBar.setVisibility(View.INVISIBLE);
    mHintView.setVisibility(View.INVISIBLE);
    if (state == STATE_READY) {
        mHintView.setVisibility(View.VISIBLE);
        mHintView.setText(R.string.xlistview_footer_hint_ready);
    } else if (state == STATE_LOADING) {
        mProgressBar.setVisibility(View.VISIBLE);
    } else {
        mHintView.setVisibility(View.VISIBLE);
        mHintView.setText(R.string.xlistview_footer_hint_normal);
    }
}

public void setBottomMargin(int height) {
    if (height < 0) return ;
    LayoutParams lp = (LayoutParams)mContentView.getLayoutParams();
    lp.bottomMargin = height;
    mContentView.setLayoutParams(lp);
}

public int getBottomMargin() {
    LayoutParams lp = (LayoutParams)mContentView.getLayoutParams();
    return lp.bottomMargin;
}


/**
 * normal status
 */
public void normal() {
    mHintView.setVisibility(View.VISIBLE);
    mProgressBar.setVisibility(View.GONE);
}


/**
 * loading status 
 */
public void loading() {
    mHintView.setVisibility(View.GONE);
    mProgressBar.setVisibility(View.VISIBLE);
}

/**
 * hide footer when disable pull load more
 */
public void hide() {
    LayoutParams lp = (LayoutParams)mContentView.getLayoutParams();
    lp.height = 0;
    mContentView.setLayoutParams(lp);
}

/**
 * show footer
 */
public void show() {
    LayoutParams lp = (LayoutParams)mContentView.getLayoutParams();
    lp.height = LayoutParams.WRAP_CONTENT;
    mContentView.setLayoutParams(lp);
}

private void initView(Context context) {
    mContext = context;
    LinearLayout moreView = (LinearLayout)LayoutInflater.from(mContext).inflate(R.layout.xlistview_footer, null);
    addView(moreView);
    moreView.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));

    mContentView = moreView.findViewById(R.id.xlistview_footer_content);
    mProgressBar = moreView.findViewById(R.id.xlistview_footer_progressbar);
    mHintView = (TextView)moreView.findViewById(R.id.xlistview_footer_hint_textview);
}

}

XListViewFooter

public class XListViewHeader extends LinearLayout {
private LinearLayout mContainer;
private ImageView mArrowImageView;
private ProgressBar mProgressBar;
private TextView mHintTextView;
private int mState = STATE_NORMAL;

private Animation mRotateUpAnim;
private Animation mRotateDownAnim;

private final int ROTATE_ANIM_DURATION = 180;

public final static int STATE_NORMAL = 0;
public final static int STATE_READY = 1;
public final static int STATE_REFRESHING = 2;

public XListViewHeader(Context context) {
    super(context);
    initView(context);
}

/**
 * @param context
 * @param attrs
 */
public XListViewHeader(Context context, AttributeSet attrs) {
    super(context, attrs);
    initView(context);
}

private void initView(Context context) {
    // 初始情况,设置下拉刷新view高度为0
    LayoutParams lp = new LayoutParams(
            LayoutParams.FILL_PARENT, 0);
    // 将下拉刷新的view添加进来
    mContainer = (LinearLayout) LayoutInflater.from(context).inflate(
            R.layout.xlistview_header, null);
    addView(mContainer, lp);
    setGravity(Gravity.BOTTOM);

    mArrowImageView = (ImageView) findViewById(R.id.xlistview_header_arrow);
    mHintTextView = (TextView) findViewById(R.id.xlistview_header_hint_textview);
    mProgressBar = (ProgressBar) findViewById(R.id.xlistview_header_progressbar);
    // 准备向上和向下的动画
    mRotateUpAnim = new RotateAnimation(0.0f, -180.0f,
            Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
            0.5f);
    // 设置旋转时间间隔
    mRotateUpAnim.setDuration(ROTATE_ANIM_DURATION);
    mRotateUpAnim.setFillAfter(true);
    mRotateDownAnim = new RotateAnimation(-180.0f, 0.0f,
            Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
            0.5f);
    mRotateDownAnim.setDuration(ROTATE_ANIM_DURATION);
    mRotateDownAnim.setFillAfter(true);
}

public void setState(int state) {
    if (state == mState)
        return;
    // 如果当前状态是正在刷新
    if (state == STATE_REFRESHING) { // 显示进度
        // 移除动画
        mArrowImageView.clearAnimation();
        // 设置imageView不可见
        mArrowImageView.setVisibility(View.INVISIBLE);
        // 设置progressBar可见
        mProgressBar.setVisibility(View.VISIBLE);
    } else { // 显示箭头图片
        // 只要不是正在刷新,进度条可见,imageView不可见
        mArrowImageView.setVisibility(View.VISIBLE);
        mProgressBar.setVisibility(View.INVISIBLE);
    }

    switch (state) {
    case STATE_NORMAL:
        if (mState == STATE_READY) {
            mArrowImageView.startAnimation(mRotateDownAnim);
        }
        if (mState == STATE_REFRESHING) {
            mArrowImageView.clearAnimation();
        }
        mHintTextView.setText(R.string.xlistview_header_hint_normal);
        break;
    case STATE_READY:
        if (mState != STATE_READY) {
            mArrowImageView.clearAnimation();
            mArrowImageView.startAnimation(mRotateUpAnim);
            mHintTextView.setText(R.string.xlistview_header_hint_ready);
        }
        break;
    case STATE_REFRESHING:
        mHintTextView.setText(R.string.xlistview_header_hint_loading);
        break;
    default:
    }
    mState = state;
}

public void setVisiableHeight(int height) {
    if (height < 0)
        height = 0;
    LayoutParams lp = (LayoutParams) mContainer
            .getLayoutParams();
    lp.height = height;
    mContainer.setLayoutParams(lp);
}

public int getVisiableHeight() {
    return mContainer.getLayoutParams().height;
}

}

Layout _ xlistview_footer

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源
大学生在线租房平台管理系统按照操作主体分为管理员和用户。管理员的功能包括报修管理、报修评价管理、字典管理、房东管理、房屋管理、房屋收藏管理、房屋留言管理、房屋租赁管理、租房论坛管理、公告信息管理、留言板管理、用户管理、管理员管理。用户的功能等。该系统采用了Mysql数据库,Java语言,Spring Boot框架等技术进行编程实现。 大学生在线租房平台管理系统可以提高大学生在线租房平台信息管理问题的解决效率,优化大学生在线租房平台信息处理流程,保证大学生在线租房平台信息数据的安全,它是一个非常可靠,非常安全的应用程序。 管理员权限操作的功能包括管理公告,管理大学生在线租房平台信息,包括房屋管理,培训管理,报修管理,薪资管理等,可以管理公告。 房屋管理界面,管理员在房屋管理界面中可以对界面中显示,可以对房屋信息的房屋状态进行查看,可以添加新的房屋信息等。报修管理界面,管理员在报修管理界面中查看报修种类信息,报修描述信息,新增报修信息等。公告管理界面,管理员在公告管理界面中新增公告,可以删除公告。公告类型管理界面,管理员在公告类型管理界面查看公告的工作状态,可以对公告的数据进行导出,可以添加新公告的信息,可以编辑公告信息,删除公告信息。
基于hal库的OLED显示屏驱动C语言实现源码.zip 【备注】 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用!有问题请及时沟通交流。 2、适用人群:计算机相关专业(如计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网、自动化、电子信息等)在校学生、专业老师或者企业员工下载使用。 3、用途:项目具有较高的学习借鉴价值,不仅适用于小白学习入门进阶。也可作为毕设项目、课程设计、大作业、初期项目立项演示等。 4、如果基础还行,或热爱钻研,亦可在此项目代码基础上进行修改添加,实现其他不同功能。 欢迎下载!欢迎交流学习!不清楚的可以私信问我! 基于hal库的OLED显示屏驱动C语言实现源码.zip基于hal库的OLED显示屏驱动C语言实现源码.zip基于hal库的OLED显示屏驱动C语言实现源码.zip基于hal库的OLED显示屏驱动C语言实现源码.zip基于hal库的OLED显示屏驱动C语言实现源码.zip基于hal库的OLED显示屏驱动C语言实现源码.zip基于hal库的OLED显示屏驱动C语言实现源码.zip基于hal库的OLED显示屏驱动C语言实现源码.zip基于hal库的OLED显示屏驱动C语言实现源码.zip基于hal库的OLED显示屏驱动C语言实现源码.zip基于hal库的OLED显示屏驱动C语言实现源码.zip基于hal库的OLED显示屏驱动C语言实现源码.zip基于hal库的OLED显示屏驱动C语言实现源码.zip
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值