IndexableListView的中国化版本

android通讯录实例(一) android通讯录,实现功能1.检索手机存入联系人并显示 2.右侧导航条根据拼音字母检索联系人 3.通过搜索栏实时搜索联系人 4.vCard格式导出并发送分享功能 5.检测系统通讯录是否有变化,有变化在通知栏通知,并更新联系人列表功能 阅读详情

IndexableListView常用于联系人APP及音乐播放器类APP,能快速定位到想到达的位置。
这个版本是在woozzu的Github项目基础上,增加网友翻译的中文注释以及支持中英文混合排序,来不及对性能进行优化,有方向的网友可以在评论进行讨论。

主要源码如下:
IndexableListViewActivity.java

package com.itant.indexablelistview;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.text.TextUtils;
import android.widget.ArrayAdapter;
import android.widget.SectionIndexer;

import com.itant.indexablelistview.utils.Hanzi2Pinyin;
import com.itant.indexablelistview.view.IndexableListView;

public class IndexableListViewActivity extends Activity {
    private ArrayList<String> mItems;
    private IndexableListView mListView;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        mItems = new ArrayList<String>();
        mItems.add("Diary of a Wimpy Kid 6: Cabin Fever");
        mItems.add("Steve Jobs");
        mItems.add("Inheritance (The Inheritance Cycle)");
        mItems.add("哈哈: A Novel");
        mItems.add("大 Hunger Games");
        mItems.add("Catching Fire (The Second Book of the Hunger Games)");
        mItems.add("Death Comes to Pemberley");
        mItems.add("Diary of a Wimpy Kid 6: Cabin Fever");
        mItems.add("Steve Jobs");
        mItems.add("11/22/63: A Novel");
        mItems.add("The Hunger Games");
        mItems.add("The LEGO Ideas Book");
        mItems.add("Explosive Eighteen: A Stephanie Plum Novel");
        mItems.add("Elder Scrolls V: Skyrim: Prima Official Game Guide");

        Collections.sort(mItems, new Comparator<String>() {

            @Override
            public int compare(String lhs, String rhs) {
                Hanzi2Pinyin hanzi2Pinyin = new Hanzi2Pinyin();
                // TODO Auto-generated method stub
                return hanzi2Pinyin.getStringPinYin(lhs.replaceAll(" ", "")).compareToIgnoreCase(hanzi2Pinyin.getStringPinYin(rhs.replaceAll(" ", "")));
            }
        });

        ContentAdapter adapter = new ContentAdapter(this,
                android.R.layout.simple_list_item_1, mItems);

        mListView = (IndexableListView) findViewById(R.id.listview);
        mListView.setAdapter(adapter);
        mListView.setFastScrollEnabled(true);
    }

    private class ContentAdapter extends ArrayAdapter<String> implements SectionIndexer {

        private String mSections = "#ABCDEFGHIJKLMNOPQRSTUVWXYZ";

        public ContentAdapter(Context context, int textViewResourceId,
                List<String> objects) {
            super(context, textViewResourceId, objects);
        }

        @Override
        public int getPositionForSection(int section) {
            // section:所点击字母在右侧数组中的位置,从0开始。
            // getCount():ListView的总条目数
            // 查找结束后的i:真正聚焦的字母在右侧数组中的位置(如果ListView中不存在当前点击的字母,则往前面聚焦。)
            // 查找结束后的j:所点击的字母在ListView的位置(如果ListView中不存在当前点击的字母,则往前面聚焦。)
            for (int i = section; i >= 0; i--) {
                for (int j = 0; j < getCount(); j++) {
                    if (i == 0) {
                        // 点击的是数字(或者点击的字母在LIstView项的首字母中没找到)
                        for (int k = 0; k <= 9; k++) {
                            //if (StringMatcher.match(String.valueOf(getItem(j).charAt(0)), String.valueOf(k)))
                            if (TextUtils.equals(String.valueOf(getItem(j).charAt(0)), String.valueOf(k)))
                                return j;
                        }
                    } else {
                        // 用ListView每一项的首字母与点击的右侧字母进行对比
                        if (TextUtils.equals(String.valueOf(getItem(j).charAt(0)), String.valueOf(mSections.charAt(i))))
                            return j;
                    }
                }
            }
            return 0;
        }

        @Override
        public int getSectionForPosition(int position) {
            return 0;
        }

        @Override
        public Object[] getSections() {
            String[] sections = new String[mSections.length()];
            for (int i = 0; i < mSections.length(); i++)
                sections[i] = String.valueOf(mSections.charAt(i));
            return sections;
        }
    }
}

用于将汉字转换为拼音的类Hanzi2Pinyin.java

package com.itant.indexablelistview.utils;

import net.sourceforge.pinyin4j.PinyinHelper;
import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;
import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;

public class Hanzi2Pinyin {
    private HanyuPinyinOutputFormat format = null;

    private String[] pinyin;

    public Hanzi2Pinyin() {
        format = new HanyuPinyinOutputFormat();
        format.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
        pinyin = null;

    }

    // 转换单个字符
    public String getCharacterPinYin(char c) {
        try {

            pinyin = PinyinHelper.toHanyuPinyinStringArray(c, format);

        }
        catch (BadHanyuPinyinOutputFormatCombination e) {
            e.printStackTrace();
        }

        // 如果c不是汉字,toHanyuPinyinStringArray会返回null
        if (pinyin == null) {
            if (c >= 'A' && c <= 'Z' || c >= 'a' && c <= 'z') {
                return String.valueOf(c);
            }
            return null;
        }
        // 只取一个发音,如果是多音字,仅取第一个发音
        return pinyin[0];
    }

    // 转换一个字符串

    public String getStringPinYin(String str) {
        StringBuilder sb = new StringBuilder();
        String tempPinyin = null;
        for (int i = 0; i < str.length(); ++i) {
            tempPinyin = getCharacterPinYin(str.charAt(i));
            if (tempPinyin == null) {
                // 如果str.charAt(i)非汉字,且不是数字,则置空
                char character = str.charAt(i);
                if (character >= '0' && character <= '9') {
                    sb.append(character);
                }
            } else {
                sb.append(tempPinyin);
            }
        }
        return sb.toString();
    }
}

自定义控件IndexableListView.java

/*
 * Copyright 2011 woozzu
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.itant.indexablelistview.view;

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

public class IndexableListView extends ListView {

    private boolean mIsFastScrollEnabled = false;
    private IndexScroller mScroller = null;
    private GestureDetector mGestureDetector = null;

    public IndexableListView(Context context) {
        super(context);
    }

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

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

    @Override
    public boolean isFastScrollEnabled() {
        return mIsFastScrollEnabled;
    }

    @Override
    public void setFastScrollEnabled(boolean enabled) {
        mIsFastScrollEnabled = enabled;
        if (mIsFastScrollEnabled) {
            if (mScroller == null)
                mScroller = new IndexScroller(getContext(), this);
        } else {
            if (mScroller != null) {
                mScroller.hide();
                mScroller = null;
            }
        }
    }

    @Override
    public void draw(Canvas canvas) {
        super.draw(canvas);

        // Overlay index bar
        if (mScroller != null)
            mScroller.draw(canvas);
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        // 创建一个GestureDetector(手势探测器)
        if (mScroller != null && mScroller.onTouchEvent(ev))
            return true;

        if (mGestureDetector == null) {
            mGestureDetector = new GestureDetector(getContext(), new GestureDetector.SimpleOnGestureListener() {

                @Override
                public boolean onFling(MotionEvent e1, MotionEvent e2,
                        float velocityX, float velocityY) {
                    // 快速掠过屏幕,则显示索引条
                    if (mScroller != null)
                        mScroller.show();
                    return super.onFling(e1, e2, velocityX, velocityY);
                }

            });
        }
        mGestureDetector.onTouchEvent(ev);

        return super.onTouchEvent(ev);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        if(mScroller.contains(ev.getX(), ev.getY()))
            return true;

        return super.onInterceptTouchEvent(ev);
    }

    @Override
    public void setAdapter(ListAdapter adapter) {
        super.setAdapter(adapter);
        if (mScroller != null)
            mScroller.setAdapter(adapter);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        if (mScroller != null)
            mScroller.onSizeChanged(w, h, oldw, oldh);
    }

}

右侧索引条IndexScroller.java

/*
 * Copyright 2011 woozzu
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.itant.indexablelistview.view;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
import android.view.MotionEvent;
import android.widget.Adapter;
import android.widget.ListView;
import android.widget.SectionIndexer;

public class IndexScroller {

    private float mIndexbarWidth;// 索引条宽度
    private float mIndexbarMargin;// 索引条外边距
    private float mPreviewPadding;
    private float mDensity;// 密度
    private float mScaledDensity;// 缩放密度  
    private float mAlphaRate;// 透明度  
    private int mState = STATE_HIDDEN;// 状态
    private int mListViewWidth;// ListView宽度
    private int mListViewHeight;// ListView高度
    private int mCurrentSection = -1;// 当前部分  
    private boolean mIsIndexing = false;// 是否正在索引
    private ListView mListView = null;
    private SectionIndexer mIndexer = null;
    private String[] mSections = null;
    private RectF mIndexbarRect;

    // 4种状态(已隐藏、正在显示、已显示、正在隐藏)
    private static final int STATE_HIDDEN = 0;
    private static final int STATE_SHOWING = 1;
    private static final int STATE_SHOWN = 2;
    private static final int STATE_HIDING = 3;

    public IndexScroller(Context context, ListView lv) {
        mDensity = context.getResources().getDisplayMetrics().density;
        mScaledDensity = context.getResources().getDisplayMetrics().scaledDensity;
        mListView = lv;
        setAdapter(mListView.getAdapter());

        mIndexbarWidth = 20 * mDensity;// 索引条宽度 20dp,转换为px
        mIndexbarMargin = 10 * mDensity;// 索引条间距 10dp,转换为px
        mPreviewPadding = 5 * mDensity;// 内边距 5dp,转换为px
    }

    public void draw(Canvas canvas) {
        if (mState == STATE_HIDDEN)
            return;

        // mAlphaRate determines the rate of opacity
        Paint indexbarPaint = new Paint();
        indexbarPaint.setColor(Color.BLACK);
        indexbarPaint.setAlpha((int) (64 * mAlphaRate));
        indexbarPaint.setAntiAlias(true);
        // 画右侧字母索引的圆矩形  
        canvas.drawRoundRect(mIndexbarRect, 5 * mDensity, 5 * mDensity, indexbarPaint);

        if (mSections != null && mSections.length > 0) {
            // Preview is shown when mCurrentSection is set
            if (mCurrentSection >= 0) {
                Paint previewPaint = new Paint();// 用来绘画所以条背景的画笔 
                previewPaint.setColor(Color.BLACK);// 设置画笔颜色为黑色  
                previewPaint.setAlpha(96);// 设置透明度  
                previewPaint.setAntiAlias(true);// 设置抗锯齿  
                previewPaint.setShadowLayer(3, 0, 0, Color.argb(64, 0, 0, 0));// 设置阴影层  

                // 屏幕中间的大字母
                Paint previewTextPaint = new Paint();// 用来绘画索引字母的画笔  
                previewTextPaint.setColor(Color.WHITE);// 设置画笔为白色
                previewTextPaint.setAntiAlias(true);// 设置抗锯齿
                previewTextPaint.setTextSize(50 * mScaledDensity);// 设置字体大小  

                // 文本的宽度  
                float previewTextWidth = previewTextPaint.measureText(mSections[mCurrentSection]);
                float previewSize = 2 * mPreviewPadding + previewTextPaint.descent() - previewTextPaint.ascent();
                RectF previewRect = new RectF((mListViewWidth - previewSize) / 2
                        , (mListViewHeight - previewSize) / 2
                        , (mListViewWidth - previewSize) / 2 + previewSize
                        , (mListViewHeight - previewSize) / 2 + previewSize);

                // 中间索引的那个框,圆角5dp
                canvas.drawRoundRect(previewRect, 5 * mDensity, 5 * mDensity, previewPaint);

                // 屏幕中间的大字母
                canvas.drawText(mSections[mCurrentSection], previewRect.left + (previewSize - previewTextWidth) / 2 - 1
                        , previewRect.top + mPreviewPadding - previewTextPaint.ascent() + 1, previewTextPaint);



            }

            // 绘画右侧索引条的字母
            Paint indexPaint = new Paint();
            indexPaint.setColor(Color.WHITE);
            indexPaint.setAlpha((int) (255 * mAlphaRate));
            indexPaint.setAntiAlias(true);
            indexPaint.setTextSize(12 * mScaledDensity);

            float sectionHeight = (mIndexbarRect.height() - 2 * mIndexbarMargin) / mSections.length;
            float paddingTop = (sectionHeight - (indexPaint.descent() - indexPaint.ascent())) / 2;
            for (int i = 0; i < mSections.length; i++) {
                float paddingLeft = (mIndexbarWidth - indexPaint.measureText(mSections[i])) / 2;
                canvas.drawText(mSections[i], mIndexbarRect.left + paddingLeft
                        , mIndexbarRect.top + mIndexbarMargin + sectionHeight * i + paddingTop - indexPaint.ascent(), indexPaint);
                // - indexPaint.ascent()则到达基线
            }
        }
    }

    public boolean onTouchEvent(MotionEvent ev) {
        switch (ev.getAction()) {
        case MotionEvent.ACTION_DOWN:// 按下,开始索引
            // If down event occurs inside index bar region, start indexing
            if (mState != STATE_HIDDEN && contains(ev.getX(), ev.getY())) {
                setState(STATE_SHOWN);

                // It demonstrates that the motion event started from index bar
                mIsIndexing = true;
                // Determine which section the point is in, and move the list to that section
                mCurrentSection = getSectionByPoint(ev.getY());
                mListView.setSelection(mIndexer.getPositionForSection(mCurrentSection));
                return true;
            }
            break;
        case MotionEvent.ACTION_MOVE:// 移动 
            if (mIsIndexing) {
                // If this event moves inside index bar
                if (contains(ev.getX(), ev.getY())) {
                    // Determine which section the point is in, and move the list to that section
                    mCurrentSection = getSectionByPoint(ev.getY());
                    mListView.setSelection(mIndexer.getPositionForSection(mCurrentSection));
                }
                return true;
            }
            break;
        case MotionEvent.ACTION_UP:// 抬起
            if (mIsIndexing) {
                mIsIndexing = false;
                mCurrentSection = -1;
            }
            if (mState == STATE_SHOWN)
                setState(STATE_HIDING);
            break;
        }
        return false;
    }

    public void onSizeChanged(int w, int h, int oldw, int oldh) {
        mListViewWidth = w;
        mListViewHeight = h;
        mIndexbarRect = new RectF(w - mIndexbarMargin - mIndexbarWidth
                , mIndexbarMargin
                , w - mIndexbarMargin
                , h - mIndexbarMargin);
    }

    /**
     * 显示
     */
    public void show() {
        if (mState == STATE_HIDDEN)
            setState(STATE_SHOWING);
        else if (mState == STATE_HIDING)
            setState(STATE_HIDING);
    }

    /**
     * 隐藏
     */
    public void hide() {
        if (mState == STATE_SHOWN)
            setState(STATE_HIDING);
    }

    /**
     * 设置状态
     * @param adapter
     */
    public void setAdapter(Adapter adapter) {
        if (adapter instanceof SectionIndexer) {
            mIndexer = (SectionIndexer) adapter;
            mSections = (String[]) mIndexer.getSections();
        }
    }

    private void setState(int state) {
        if (state < STATE_HIDDEN || state > STATE_HIDING)
            return;

        mState = state;
        switch (mState) {
        case STATE_HIDDEN:
            // Cancel any fade effect
            // 取消渐退的效果  
            mHandler.removeMessages(0);
            break;
        case STATE_SHOWING:
            // Start to fade in
            // 开始渐进效果  
            mAlphaRate = 0;
            fade(0);
            break;
        case STATE_SHOWN:
            // Cancel any fade effect
             // 取消渐退的效果  
            mHandler.removeMessages(0);
            break;
        case STATE_HIDING:
            // Start to fade out after three seconds
            // 隐藏3秒钟  
            mAlphaRate = 1;
            fade(3000);
            break;
        }
    }

    public boolean contains(float x, float y) {
        // Determine if the point is in index bar region, which includes the right margin of the bar
        return (x >= mIndexbarRect.left && y >= mIndexbarRect.top && y <= mIndexbarRect.top + mIndexbarRect.height());
    }

    private int getSectionByPoint(float y) {
        if (mSections == null || mSections.length == 0)
            return 0;
        if (y < mIndexbarRect.top + mIndexbarMargin)
            return 0;
        if (y >= mIndexbarRect.top + mIndexbarRect.height() - mIndexbarMargin)
            return mSections.length - 1;
        return (int) ((y - mIndexbarRect.top - mIndexbarMargin) / ((mIndexbarRect.height() - 2 * mIndexbarMargin) / mSections.length));
    }

    private void fade(long delay) {
        mHandler.removeMessages(0);
        mHandler.sendEmptyMessageAtTime(0, SystemClock.uptimeMillis() + delay);
    }

    private Handler mHandler = new Handler() {

        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);

            switch (mState) {
            case STATE_SHOWING:
                // Fade in effect
                // 淡进效果 
                mAlphaRate += (1 - mAlphaRate) * 0.2;
                if (mAlphaRate > 0.9) {
                    mAlphaRate = 1;
                    setState(STATE_SHOWN);
                }

                mListView.invalidate();
                fade(10);
                break;
            case STATE_SHOWN:
                // If no action, hide automatically
                setState(STATE_HIDING);
                break;
            case STATE_HIDING:
                // Fade out effect
                // 淡出效果  
                mAlphaRate -= mAlphaRate * 0.2;
                if (mAlphaRate < 0.1) {
                    mAlphaRate = 0;
                    setState(STATE_HIDDEN);
                }

                mListView.invalidate();
                fade(10);
                break;
            }
        }

    };
}

main.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <com.itant.indexablelistview.view.IndexableListView
        android:layout_width="fill_parent" 
        android:layout_height="fill_parent" 
        android:id="@+id/listview" />
</LinearLayout>

运行效果图

汉字转拼音jar包免费下载

原始版本源码

中国化版本源码

Android 列表字母索引 IndexableListView Android代码 实现带字母索引效果的listview列表, 类似Android 通讯录中使用的检索联系人得效果.滑动listview时 旁边会出现一个字母索引条,手指滑动索引条 屏幕中间会出现当前索引字母,同时listview内容会被过滤检索,支持点击和滑动. Appdoll代码库测试,适用于Android 2.0 and up. 立即下载

相关推荐

IndexableListView

IndexableListView介绍: 当快速滑动列表(ListView)时,会在列表左侧出现索引栏(index bar)。当列表停止滚动时,索引栏会自动消失。点击索引栏上某个字母,会跳到对应的列表行。

Android UI--开源项目IndexableListView(字母索引),万分膜拜

setContentView(R.layout.main); // 初始化一些数据 mItems = new ArrayList(); mItems.add(“Diary of a Wimpy Kid 6: Cabin Fever”); mItems.add(“Steve Jobs”); mItems.add(“Inheritance (The Inheritance Cycle)”); mItems.add(“11/22/63: A Novel”); mItems.add(“The Hunger Game

wa2231a的博客 789

政府科技管理者在推动科技成果转化过程中,如何解决科研成果与市场需求脱节的问题?.docx

政府科技管理者在推动科技成果转化过程中,如何解决科研成果与市场需求脱节的问题?

IndexableListView详解之——IndexableListViewActivity

说明 现在app中经常使用到带索引条的列表,本系列就github上的一个实现索引列表功能的项目进行讲解。 该项目的地址为:https://github.com/woozzu/IndexableListView,大家可以下载运行一下,对项目有大概的了解。我大概说一下项目的功能:打开项目就是一个列表,快速滑动列表,右侧会显示索引条,用户点击索引条上的字符可定位到相应item,同时屏幕中间会出现索引

粥 1271

隔离型全桥LLC谐振变化器建模及参数设计资料【仿真+设计报告+计算书】

内容概要:本文档系统性地提供了隔离型全桥LLC谐振变换器的建模与参数设计全套资料,涵盖Simulink、Plecs和PSIM等多种主流仿真平台的实现模型,配套完整的闭环控制设计报告与Mathcad计算书。内容深入聚焦LLC谐振变换器的核心技术环节,包括软开关实现机制、变频与移相混合控制策略、闭环稳定性分析、谐振参数优化设计及软启动过程建模等关键方面。资料不仅包含典型拓扑结构的仿真验证,还整合了多相交错、双向CLLC、恒压恒流双闭环等进阶控制方案,辅以详细的数学推导与工程设计流程,全面支撑从理论分析到实际电源系统开发的全过程。; 适合人群:面向具备电力电子、自动化或电气工程等相关专业背景,从事开关电源、新能源变换系统、高效率DC-DC转换器研发的工程师、高校研究生及科研人员。; 使用场景及目标:① 深入掌握全桥LLC谐振变换器的工作原理与精确建模方法;② 学习并实践基于多平台的闭环控制系统仿真与动态性能优化;③ 借助Mathcad计算书完成实际工程中谐振腔参数、磁性元件与开关频率的系统化设计;④ 支持高水平科研论文撰写、学位课题研究或工业级电源产品的开发与验证。; 阅读建议:建议结合仿真模型、设计报告与计算书三位一体同步研习,重点剖析控制策略的实现逻辑与参数敏感性分析,动手运行并修改仿真文件以深入理解系统动态响应,同时可参照文档中丰富的电力电子拓扑案例进行横向对比与技术拓展。

Android BluetoothSocket

BluetoothSocket是Android中用于在蓝牙设备之间进行数据传输的一种Socket。它提供了一种类似于TCP/IP协议的数据传输方式,可以在两个设备之间建立一个虚拟的通信管道,使得两个设备之间可以进行数据的传输和接收。BluetoothSocket可以用于客户端和服务端之间的通信,通过BluetoothSocket可以实现数据的双向传输。

liuning1985622的博客 1477

IndexableListView: 提高Android ListView的可读性和易用性

IndexableListView: 提高Android ListView的可读性和易用性 简介 在开发Android应用时,ListView是一种常见的组件,用于显示大量的数据列表。然而,默认的ListView在处理大量数据时可能会出现性能问题,并且不支持快速索引。为了解决这些问题,我们推出了IndexableListView。 IndexableListView是一个基于ListView的自定...

gitblog_00092的博客 537

PCIe中ACS知识小记

虚拟机内部的访问数据显而易见是带的GPA地址。而目前几乎所有的PCIe 设备都带ACS control,所以它们可以单独assign给不同的VM,但是随之而来的就是即使两个GPU同时assign给同一个VM,由于ACS的存在,他们之间也不会有真正的物理层面的P2P访问。每一个TLP都自带一个address(寻址类TLP),同时每一个endpoint,PCIe switch都自带一段BIOS配置的地址空间范围,一旦这个TLP的address落入某个设备的地址范围,那么这个TLP就属于这个设备并消费。

Summer的博客 5078

Android UI--开源项目IndexableListView(字母索引)

AndroidUI效果--开源项目IndexableListView(字母索引) 2013年12月13日 开源项目IndexableListView的学习 开发通讯录相关的应用的时候可能会需要这种效果,索引这种效果根据人性化和美观,我下了一个关于字母索引的Demo,里面很好实现了这种效果,不过这只是个Demo,在实际的项目当中,可能会增加分组效果,我们可能在这个基础上

巫山老妖 1万+

AI 自动生成商业计划书:AIGC 如何助力创业者?

在创业的早期阶段,商业计划书(Business Plan)是至关重要的。它不仅用于吸引投资者、明确发展路径,还能帮助团队对业务模式、市场定位和财务预测有清晰认知。然而,撰写一份高质量的商业计划书往往需要投入大量时间和精力。如今,AIGC(AI Generated Content,人工智能生成内容)技术正在改变这一现状。借助 AIGC,创业者可以更快速、高效地创建商业计划书,并通过 AI 进行优化和数据分析。

2401_82808034的博客 3781

EV1527、PT2262傻傻分不清?一文讲透常见315/433MHz遥控编码协议区别与选型

本文深度对比了EV1527、PT2262和SC5262三种常见的315/433MHz遥控编码协议,详细解析了它们的技术特点、成本效益和适用场景。EV1527作为低成本方案的首选,特别适合智能家居和简易安防设备;PT2262在稳定性和兼容性上表现优异;而SC5262则在安全性方面具有显著优势。文章还提供了实用的选型框架和工程建议,帮助开发者在不同应用场景中做出最优决策。

weixin_33640562的博客 349

4、AndroidUI效果--开源项目IndexableListView(字母索引)

AndroidUI效果--开源项目IndexableListView(字母索引) 2013年12月13日开源项目IndexableListView的学习 开发通讯录相关的应用的时候可能会需要这种效果,索引这种效果根据人性化和美观,我下了一个关于字母索引的Demo,里面很好实现了这种效果,不过这只是个Demo,在实际的项目当中,可能会增加分组效果,我们

zwcshy的专栏 819

10分钟搞定小红书爆款笔记爬取!Selenium模拟登录+数据解析全流程,新手也能落地

小红书爬虫实战的核心,是**“模拟真人操作+解析结构化数据”**——Selenium解决了动态页面和登录的问题,lxml解决了数据提取的问题,pandas解决了数据存储的问题。新手学爬虫不用一开始就啃复杂的反爬机制,先从这类“可见即可爬”的场景入手,掌握“模拟操作→数据解析→数据保存”的全流程,再逐步叠加异常处理、批量爬取、反爬应对等功能。需要注意的是:爬取数据仅用于个人学习和研究,不得用于商业用途,且需遵守小红书的用户协议,不要过度爬取导致服务器压力。

专注于Python爬虫开发,分享爬虫技巧、项目实战与反爬经验,使用Scrapy、BeautifulSoup等工具,解决数据抓取难题。 1729

android 字母索引三方,开源项目IndexableListView(字母索引)

通讯录或者事件列表需要用到此功能,先看截图首页源码package com.woozzu.android.indexablelistview;import java.util.ArrayList;import java.util.Collections;import java.util.List;import android.app.Activity;import android.content.C...

weixin_34469152的博客 241

数字后端:版图基础seal ring

seal ring结构是为了防止划片或封装对芯片造成破坏,从而在芯片与划片道(scribe line)之间添加的一圈保护环

m0_61544122的博客 1万+

YOLOv11改进 - 卷积Conv | PATConv(Partial Attention Convolution)部分注意力卷积,在减少计算量的同时融合卷积与注意力的优势 | AAAI 2026

本文提出部分注意力卷积(PATConv)机制,并将其集成到YOLOv11中。传统神经网络中,卷积计算密集,注意力机制全局计算冗余,此前的“部分卷积”会丢失未计算通道的特征价值。PATConv通过“通道拆分 - 并行处理 - 结果拼接”的逻辑,给不同通道分配“擅长的任务”,兼顾局部与全局特征。基于此,它还衍生出PAT_ch、PAT_sp和PAT_sf三种细分模块。此外,还提出了动态部分卷积(DPConv),并构建了新的混合网络家族PartialNet。我们将PATConv代码集成到YOLOv11中,实验表明,

魔改工程师的博客 1085

IndexableListView详解之——StringMatcher

这是IndexableListView项目详解系列的第二篇博客,还没看第一篇博客的小伙伴们建议先看哦,链接: IndexableListView详解之——IndexableListViewActivity,简单介绍了整个项目的结构、讲解了IndexableListViewActivity。 这里来讲一讲IndexableListView项目中用到的字符匹配工具类StringMatcher,整

粥 882

基于IEEE39节点系统的风力发电机组并网改造与稳定性研究

本文研究了基于IEEE39节点系统的风力发电机组并网改造与稳定性问题。首先将系统工作频率从60Hz转换为50Hz,并对同步发电机、变压器、线路和负荷参数进行相应调整。随后将30、32、34、37号节点的同步发电机替换为不同容量的永磁同步发电机(PMSG)和双馈感应发电机(DFIG),详细建立了两种风电机组的数学模型和控制策略。通过Simulink仿真验证,改造后的系统能够稳定运行并满足并网要求。研究成果为大规模风电并网系统仿真提供了参考,对提高电力系统可再生能源消纳能力具有重要意义。

huanghm88的专栏 110

Andorid学习笔记 :实现对ListView列表数据添加字母索引效果

在我们的项目开发中,用到列表控件ListView的机率通过是100%,不过有时候我们在用ListView展示数据的时候,还需要做点美化,比如为了方便查找列表中的数据,我们会给列表数据加个索引功能,就是在屏幕的右边有一个条形的悬浮框显示在Listview上,最典型的例子就是诸如小米手机的联系人列表,右侧有一个#ABC......的索引条,还用很多应用的城市数据列表等,都有这个功能。 小米手机联系人

true100的专栏 1971

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

Android 自定义控件实现ListView索引

实现listview 的索引 中间的预览文本因为截图水平有限没有截出来。。源代码下载地址:实现该方法需要重写lisetview 控件。实现步骤如下 1. 新建一个数组 用于存放右侧的a-z 的26个字母 然后写自定义空间IndexLisetview 2.IndexLisetview继承Lisetview 然后重写setFastScrollEnabled 、 draw、onTouchEvent、s

哎幽的成长 1124

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

IndexableListView详解之——IndexScroller

这是IndexableListView项目详解系列的第四篇博客,也是最后一篇啦,还没看第一篇博客的小伙伴们建议先看哦,链接:IndexableListView详解之——IndexableListViewActivity,简单介绍了整个项目的结构、讲解了IndexableListViewActivity。 这一篇讲的是IndexableListView项目中的重中之重——IndexScro

粥 1061

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

IndexableListView详解之——IndexableListView

这是IndexableListView项目详解系列的第三篇博客,还没看第一篇博客的小伙伴们建议先看哦,链接: IndexableListView详解之——IndexableListViewActivity,简单介绍了整个项目的结构、讲解了IndexableListViewActivity。 这一篇讲的是自定义索引列表IndexableListView,是这个项目的重点之一。

粥 790
上一篇: 刚切换就让PullToRefreshListView呈现下拉状态刷新
下一篇: Github添加图片说明
ithouse
博客等级 码龄12年 200粉丝 212原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ithouse

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值