React-native实现联系人列表分组组件_recipient list 如何分组-程序员宅基地

技术标签: react.js  react  react native  

React-native实现联系人列表分组组件(支持拼音搜索)

参考资料:

React Native使用SectionList打造城市选择列表,包含分组的跳转:https://blog.csdn.net/sinat_17775997/article/details/71424324?utm_medium=distribute.pc_relevant.none-task-blog-OPENSEARCH-5&depth_1-utm_source=distribute.pc_relevant.none-task-blog-OPENSEARCH-5

一. 功能特性和效果图
功能特性如下:

  • 支持首字母和首个汉字分组检索。

  • 支持右侧分组字母的跳转控制。

  • 支持拼音搜索。

  • 支持批量选择功能、重置功能。

效果图:

二. 技术要点

  1. SectionList列表分组组件。
  • https://reactnative.cn/docs/sectionlist
  1. pinyin。 这是一个JS拼音工具开源库。
  • 它的用途是将中文转化为拼音。

  • https://github.com/hotoo/pinyin

三. 实现思路

  1. 将联系人列表中的数据项转化为拼音存储,以便于拼音搜索。

  2. 遍历联系人列表,获取字母分组,得到一个set集合,并且转化为数组,该数组用于渲染右侧字母导航组件。

  3. 构建SectionList组件渲染数据所需要的列表数据结构,其数组元素结构为:{title:‘分组名称’,data:[]},其中,title表示分组名称,data表示该分组的数据列表。

遍历遍历联系人列表,根据首字母分组汇总,得到SectionList组件渲染数据所需要的列表数据结构。

四. 关键代码

  1. 将联系人列表中的数据项转化为拼音存储,以便于拼音搜索。

componentWillMount = () => {
// 将数据列表转化为拼音存储,以便于拼音搜索
testData.forEach((item, index, arr) => {
// 将Item的名称转为拼音数组
let pinyinArr = pinyin(item.name, {style: pinyin.STYLE_NORMAL});
item.pinyinArr = pinyinArr;
let pinyinArrStr = ‘’;
// 将拼音数组转化为一个字符串,以支持拼音搜索
for (let i = 0; i < pinyinArr.length; i++) {
for (let j = 0; j < pinyinArr[i].length; j++) {
pinyinArrStr = pinyinArrStr + pinyinArr[i][j];
}
}
item.pinyinArrStr = pinyinArrStr;
});
this.transferToSectionsData(testData);
};
2. 搜索方法

search = () => {
// alert(‘搜索’);
const {dataList, searchValue} = this.state;
if (searchValue && searchValue.trim()) {
let searchValueTemp = searchValue.toLocaleLowerCase();
const resultList = [];
dataList.forEach((item, index, arr) => {
if (item.name) {
if (item.name.toLocaleLowerCase().indexOf(searchValueTemp) >= 0
|| this.pinyinSingleLetterIndexSearch(searchValueTemp, item.pinyinArr) >= 0
|| item.pinyinArrStr.toLocaleLowerCase().indexOf(searchValueTemp) >= 0) {
resultList.push(item);
}
}
});
console.log(‘search.resultList:’, resultList);
this.transferToSectionsData(resultList);
} else {
this.transferToSectionsData(dataList);
}
};

/**
 * 在拼音数组中搜索单个拼音,如果匹配,则返回等于大于0的值,否则返回-1
 * @param keyword
 * @param pinyinArr
 * @returns {number}
 */
pinyinSingleLetterIndexSearch = (keyword, pinyinArr) => {
    let result = -1;
    if (keyword && pinyinArr) {
        for (let i = 0; i < pinyinArr.length; i++) {
            for (let j = 0; j < pinyinArr[i].length; j++) {
                let singleLetterIndex = pinyinArr[i][j].toLocaleLowerCase().indexOf(keyword);
                if (singleLetterIndex >= 0) {
                    return singleLetterIndex;
                }
            }
        }
    }
    return result;
};

五. 完整代码
注意:图片资源需自行补充。

/**
*

  • @author chenlw
  • @date 2020/04/18
    */
    import React from ‘react’;
    import {
    Dimensions,
    FlatList,
    SectionList,
    StyleSheet,
    Text,
    TouchableOpacity,
    View,
    SafeAreaView,
    Image,
    TextInput,
    Platform,
    StatusBar,
    } from ‘react-native’;

import pinyin from ‘pinyin’;

let testData = [
{id: ‘盖伦’, name: ‘盖伦’},
{id: ‘崔丝塔娜’, name: ‘崔丝塔娜’},
{id: ‘大发明家’, name: ‘大发明家’},
{id: ‘武器大师’, name: ‘武器大师’},
{id: ‘刀妹’, name: ‘刀妹’},
{id: ‘卡特琳娜’, name: ‘卡特琳娜’},
{id: ‘盲僧’, name: ‘盲僧’},
{id: ‘蕾欧娜’, name: ‘蕾欧娜’},
{id: ‘拉克丝’, name: ‘拉克丝’},
{id: ‘剑圣’, name: ‘剑圣’},
{id: ‘赏金’, name: ‘赏金’},
{id: ‘发条’, name: ‘发条’},
{id: ‘瑞雯’, name: ‘瑞雯’},
{id: ‘提莫’, name: ‘提莫’},
{id: ‘卡牌’, name: ‘卡牌’},
{id: ‘剑豪’, name: ‘剑豪’},
{id: ‘琴女’, name: ‘琴女’},
{id: ‘木木’, name: ‘木木’},
{id: ‘雪人’, name: ‘雪人’},
{id: ‘安妮’, name: ‘安妮’},
{id: ‘薇恩’, name: ‘薇恩’},
{id: ‘小法师’, name: ‘小法师’},
{id: ‘艾尼维亚’, name: ‘艾尼维亚’},
{id: ‘奥瑞利安索尔’, name: ‘奥瑞利安索尔’},
{id: ‘布兰德’, name: ‘布兰德’},
{id: ‘凯特琳’, name: ‘凯特琳’},
{id: ‘虚空’, name: ‘虚空’},
{id: ‘机器人’, name: ‘机器人’},
{id: ‘挖掘机’, name: ‘挖掘机’},
{id: ‘EZ’, name: ‘EZ’},
{id: ‘暴走萝莉’, name: ‘暴走萝莉’},
{id: ‘艾克’, name: ‘艾克’},
{id: ‘波比’, name: ‘波比’},
{id: ‘赵信’, name: ‘赵信’},
{id: ‘牛头’, name: ‘牛头’},
{id: ‘九尾’, name: ‘九尾’},
{id: ‘菲兹’, name: ‘菲兹’},
{id: ‘寒冰’, name: ‘寒冰’},
{id: ‘猴子’, name: ‘猴子’},
{id: ‘深渊’, name: ‘深渊’},
{id: ‘凯南’, name: ‘凯南’},
{id: ‘诺克萨斯’, name: ‘诺克萨斯’},
{id: ‘祖安’, name: ‘祖安’},
{id: ‘德莱文’, name: ‘德莱文’},
{id: ‘德玛西亚王子’, name: ‘德玛西亚王子’},
{id: ‘豹女’, name: ‘豹女’},
{id: ‘皮城执法官’, name: ‘皮城执法官’},
{id: ‘泽拉斯’, name: ‘泽拉斯’},
{id: ‘岩雀’, name: ‘岩雀’},
];
const selectedFieldName = ‘id’;

const isAndroid = Platform.OS === ‘android’;
export default class IndexListComponentExample extends React.PureComponent {

constructor(props) {
    super(props);
    this.state = {
        searchValue: null,

        dataList: testData,
        sections: [],       //section数组
        // letterArr: ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'],      //首字母数组
        letterArr: [],      //首字母数组
        activeLetterIndex: 0,
        selectedItemSet: new Set(),

        // 是否开启批量选择模式
        batchSelected: true,
        refreshCount: 0,
    };
}

componentWillMount = () => {
    // 将数据列表转化为拼音存储,以便于拼音搜索
    testData.forEach((item, index, arr) => {
        // 将Item的名称转为拼音数组
        let pinyinArr = pinyin(item.name, {style: pinyin.STYLE_NORMAL});
        item.pinyinArr = pinyinArr;
        let pinyinArrStr = '';
        // 将拼音数组转化为一个字符串,以支持拼音搜索
        for (let i = 0; i < pinyinArr.length; i++) {
            for (let j = 0; j < pinyinArr[i].length; j++) {
                pinyinArrStr = pinyinArrStr + pinyinArr[i][j];
            }
        }
        item.pinyinArrStr = pinyinArrStr;
    });
    this.transferToSectionsData(testData);
};

/**
 * 转化数据列表
 */
transferToSectionsData = (dataList) => {
    //获取联系人列表
    let sections = [], letterArr = [];
    // 右侧字母栏数据处理
    dataList.forEach((item, index, arr) => {
        let itemTemp = pinyin(item.name.substring(0, 1), {
            style: pinyin.STYLE_FIRST_LETTER,
        })[0][0].toUpperCase();
        letterArr.push(itemTemp);
    });
    letterArr = [...new Set(letterArr)].sort();
    this.setState({letterArr: letterArr});

    // 分组数据处理
    letterArr.forEach((item, index, arr) => {
        sections.push({
            title: item,
            data: [],
        });
    });

    dataList.forEach((item1, index1, arr1) => {
        let listItem = item1;
        sections.forEach((item2, index2, arr2) => {
            let firstName = listItem.name.substring(0, 1);
            let firstLetter = pinyin(firstName, {style: pinyin.STYLE_FIRST_LETTER})[0][0].toUpperCase();
            let pinyinStrArr = pinyin(listItem.name, {style: pinyin.STYLE_NORMAL});
            console.log('pinyinStr', pinyinStrArr);
            if (item2.title === firstLetter) {
                item2.data.push({
                    firstName: firstName,
                    name: listItem.name,
                    id: listItem.id,
                });
            }
        });
    });
    this.setState({sections: sections});
};

openBatchSelectedMode = (callback) => {
    this.setState({
        batchSelected: true,
        selectedItemSet: new Set(),
    }, () => {
        callback && callback();
    });
};

closeBatchSelectedMode = () => {
    this.setState({
        batchSelected: false,
        selectedItemSet: new Set(),
    });
};

addOrDeleteSelectedItem = (item) => {
    const {batchSelected, selectedItemSet, refreshCount} = this.state;
    if (!batchSelected) {
        return;
    }
    if (item && item[selectedFieldName]) {
        if (selectedItemSet.has(item[selectedFieldName])) {
            selectedItemSet.delete(item[selectedFieldName]);
        } else {
            selectedItemSet.add(item[selectedFieldName]);
        }
        console.log('addOrDeleteSelectedItem.selectedItemSet', selectedItemSet);
        this.setState({
            selectedItemSet: selectedItemSet,
            refreshCount: refreshCount + 1,
        }, () => {

        });
    }
};

/**
 * 重置选中的成员
 */
clearSelectedItem = () => {
    const {batchSelected, selectedItemSet, refreshCount} = this.state;
    selectedItemSet.clear();
    this.setState({
        selectedItemSet: selectedItemSet,
        refreshCount: refreshCount + 1,
    }, () => {

    });
};


// 字母关联分组跳转
_onSectionselect = (key) => {
    this.setState({
        activeLetterIndex: key,
    }, () => {

    });
    this.refs._sectionList.scrollToLocation({
        itemIndex: 0,
        sectionIndex: key,
        viewOffset: 20,
    });

};

// 分组列表的头部
_renderSectionHeader(sectionItem) {
    const {section} = sectionItem;
    return (
        <View style={
   {
            height: 20,
            backgroundColor: '#e7f0f9',
            paddingHorizontal: 10,
            flexDirection: 'row',
            alignItems: 'center',
        }}>
            <Text style={
   {fontSize: 16}}>{section.title.toUpperCase()}</Text>
        </View>
    );
}

renderItemSelectedIcon = (item) => {
    if (!item) {
        return;
    }
    const {batchSelected, selectedItemSet} = this.state;
    if (batchSelected) {
        let isActive = selectedItemSet.has(item[selectedFieldName]);
        return (
            <Image
                style={
   {
                    width: 18,
                    height: 18,
                    marginRight: 10,
                }}
                source={isActive
                    ? require('@assets/icons/common/icon_item_selected.png')
                    : require('@assets/icons/common/icon_item_unselected.png')}
            />
        );
    } else {
        return null;
    }
};

_renderItem(item, index) {
    const {batchSelected} = this.state;
    return (
        <TouchableOpacity
            style={
   {
                paddingLeft: 20,
                paddingRight: 30,
                height: 50,
                flexDirection: 'row',
                justifyContent: 'flex-start',
                alignItems: 'center',
                borderBottomWidth: 1,
                borderBottomColor: '#efefef',
            }}
            activeOpacity={.75}
            onLongPress={() => {
                if (!batchSelected) {
                    this.openBatchSelectedMode(() => {
                        this.addOrDeleteSelectedItem(item);
                    });
                }
            }}
            onPress={() => {
                this.addOrDeleteSelectedItem(item);
            }}
        >
            {
                this.renderItemSelectedIcon(item)
            }
            <View style={
   {
                flexDirection: 'row',
                alignItems: 'center',
                // justifyContent: 'space-between',
                flexGrow: 1,
            }}>
                <View style={
   {
                    // padding: 10,
                    height: 30,
                    width: 30,
                    justifyContent: 'center',
                    alignItems: 'center',
                    backgroundColor: '#2988FF',
                }}>
                    <Text style={
   {
                        color: '#fff',
                        fontSize: 18,
                    }}>
                        {item.firstName}
                    </Text>
                </View>
                <View style={
   {
                    marginLeft: 10,
                }}>
                    <Text style={
   {}}>{item.name}</Text>
                </View>
            </View>
        </TouchableOpacity>
    );
}

renderBatchSelectedHeader = () => {
    const {batchSelected, selectedItemSet} = this.state;
    if (!batchSelected) {
        return (
            <View style={
   {
                paddingLeft: 10,
                paddingRight: 10,
                height: 50,
                flexDirection: 'row',
                justifyContent: 'space-between',
                alignItems: 'center',
                borderBottomWidth: 1,
                borderBottomColor: '#efefef',
            }}>
                <TouchableOpacity
                    style={
   {
                        padding: 10,
                    }}
                >
                </TouchableOpacity>
                <View style={
   {}}>
                </View>
                <TouchableOpacity
                    style={
   {
                        padding: 10,
                    }}
                    onPress={() => {
                        this.openBatchSelectedMode();
                    }}
                >
                    <Text>批量选择</Text>
                </TouchableOpacity>
            </View>
        );
    }
    return (
        <View style={
   {
            paddingLeft: 10,
            paddingRight: 10,
            height: 50,
            flexDirection: 'row',
            justifyContent: 'space-between',
            alignItems: 'center',
        }}>
            <TouchableOpacity
                style={
   {
                    padding: 10,
                }}
                onPress={() => {
                    this.closeBatchSelectedMode();
                }}
            >
                <Text>取消</Text>
            </TouchableOpacity>
            <View style={
   {}}>
                <Text>已选择{selectedItemSet.size}条记录</Text>
            </View>
            <TouchableOpacity
                style={
   {
                    padding: 10,
                }}
                onPress={() => {
                    this.closeBatchSelectedMode();
                }}
            >
                <Text>确定</Text>
            </TouchableOpacity>
        </View>
    );
};


render = () => {
    const {letterArr, sections, activeLetterIndex, batchSelected} = this.state;
    //偏移量 = (设备高度 - 字母索引高度 - 底部导航栏 - 顶部标题栏 - 24)/ 2
    let top_offset = (Dimensions.get('window').height - letterArr.length * 16 - 52 - 44 - 24) / 2;
    if (isAndroid) {
        top_offset = top_offset + StatusBar.currentHeight + 45;
    }
    return (
        <SafeAreaView style={
   {
            flex: 1,
        }}>
            {
                this.renderSearchBar()
            }
            {
                this.renderBatchSelectedHeader()
            }
            <SectionList
                ref="_sectionList"
                renderItem={({item, index}) => this._renderItem(item, index)}
                renderSectionHeader={this._renderSectionHeader.bind(this)}
                sections={sections}
                keyExtractor={(item, index) => item + index}
                ItemSeparatorComponent={() => <View/>}
            />

            {/*右侧字母栏*/}
            <View style={
   {position: 'absolute', width: 26, right: 0, top: top_offset}}>
                <FlatList
                    data={letterArr}
                    keyExtractor={(item, index) => index.toString()}
                    renderItem={({item, index}) => {
                        let isActive = index === activeLetterIndex;
                        // let textStyle = isActive ? styles.activeIndicatorText : styles.inactiveIndicatorText;
                        // let containerStyle = isActive ? styles.activeIndicatorContainer : styles.inactiveIndicatorContainer;
                        let textStyle = styles.inactiveIndicatorText;
                        let containerStyle = styles.inactiveIndicatorContainer;
                        return (
                            <TouchableOpacity
                                style={[
                                    {
                                        marginVertical: 2,
                                        height: 16,
                                        width: 16,
                                        borderRadius: 8,
                                        flexDirection: 'row',
                                        justifyContent: 'center',
                                        alignItems: 'center',
                                    },
                                    containerStyle,
                                ]}
                                onPress={() => {
                                    this._onSectionselect(index);
                                }}
                            >
                                <Text style={[{
                                    fontSize: 12,
                                }, textStyle]}>
                                    {item.toUpperCase()}
                                </Text>
                            </TouchableOpacity>
                        );
                    }}
                />
            </View>

        </SafeAreaView>
    );
};

setSearchValue = (searchValue, callback) => {
    this.setState({
        searchValue: searchValue,
    }, () => {
        callback && callback();
    });
};

search = () => {
    // alert('搜索');
    const {dataList, searchValue} = this.state;
    if (searchValue && searchValue.trim()) {
        let searchValueTemp = searchValue.toLocaleLowerCase();
        const resultList = [];
        dataList.forEach((item, index, arr) => {
            if (item.name) {
                if (item.name.toLocaleLowerCase().indexOf(searchValueTemp) >= 0
                    || this.pinyinSingleLetterIndexSearch(searchValueTemp, item.pinyinArr) >= 0
                    || item.pinyinArrStr.toLocaleLowerCase().indexOf(searchValueTemp) >= 0) {
                    resultList.push(item);
                }
            }
        });
        console.log('search.resultList:', resultList);
        this.transferToSectionsData(resultList);
    } else {
        this.transferToSectionsData(dataList);
    }
};

/**
 * 在拼音数组中搜索单个拼音,如果匹配,则返回等于大于0的值,否则返回-1
 * @param keyword
 * @param pinyinArr
 * @returns {number}
 */
pinyinSingleLetterIndexSearch = (keyword, pinyinArr) => {
    let result = -1;
    if (keyword && pinyinArr) {
        for (let i = 0; i < pinyinArr.length; i++) {
            for (let j = 0; j < pinyinArr[i].length; j++) {
                let singleLetterIndex = pinyinArr[i][j].toLocaleLowerCase().indexOf(keyword);
                if (singleLetterIndex >= 0) {
                    return singleLetterIndex;
                }
            }
        }
    }
    return result;
};

renderSearchBar = () => {
    const {searchValue} = this.state;
    return (
        <View style={
   {
            flexDirection: 'row',
            alignItems: 'center',
            paddingTop: 10,
            paddingBottom: 10,
            backgroundColor: '#fff',
            borderBottomWidth: 1,
            borderBottomColor: '#efefef',
        }}>
            <TouchableOpacity
                style={
   {
                    paddingLeft: 15,
                    paddingRight: 15,
                }}
                onPress={() => {

                }}
            >
                <Image source={require('@assets/icons/common/icon_back.png')}/>
            </TouchableOpacity>
            <View
                style={
   {
                    flex: 1,
                }}
            >
                <View style={
   {
                    height: 30,
                    backgroundColor: '#F0F0F0',
                    borderRadius: 30,
                    paddingLeft: 10,
                    flexDirection: 'row',
                    alignItems: 'center',
                    justifyContent: 'center',
                }}>
                    <Image source={require('@assets/icons/common/icon_search.png')}
                           style={
   {width: 15, height: 15}}/>
                    <TextInput
                        placeholder="输入查询内容..."
                        maxLength={100}
                        style={
   {
                            flex: 1,
                            marginLeft: 5,
                            marginRight: 5,
                            paddingTop: 5,
                            paddingBottom: 5,
                            paddingRight: 5,
                            // backgroundColor: 'pink',
                        }}
                        autoFocus={false}
                        value={searchValue}
                        onChangeText={(text) => {
                            this.setSearchValue(text, () => {
                                this.search();
                            });
                        }}
                        onSubmitEditing={() => {

                        }}
                    />
                    {
                        searchValue
                            ? <TouchableOpacity
                                style={
   {
                                    marginRight: 10,
                                }}
                                onPress={() => {
                                    this.setSearchValue(null, () => {
                                        this.search();
                                    });
                                }}
                            >
                                <Image source={require('@assets/icons/common/icon_search_cancel.png')}
                                       style={
   {
                                           width: 17,
                                           height: 17,
                                       }}
                                />
                            </TouchableOpacity>
                            : null
                    }
                </View>

            </View>
            <TouchableOpacity
                style={
   {
                    paddingLeft: 10,
                    paddingRight: 10,
                    justifyContent: 'center',
                    alignItems: 'center',
                }}
                onPress={() => {
                    this.search();
                }}
            >
                <Text style={
   {
                    color: '#2988FF',
                    fontSize: 16,
                }}>
                    搜索
                </Text>
            </TouchableOpacity>
        </View>
    );
};

}

const styles = StyleSheet.create({
taskNodeTitleText: {
color: ‘#333333’,
fontWeight: ‘bold’,
fontSize: 16,
},
inactiveIndicatorContainer: {},
activeIndicatorContainer: {
backgroundColor: ‘#2988FF’,
},
inactiveIndicatorText: {
color: ‘#666666’,
},
activeIndicatorText: {
color: ‘#fff’,
},
});

————————————————
版权声明:本文为CSDN博主「举世武双」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_33721382/article/details/106007853

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/dly15873944157/article/details/120677872

智能推荐

使用 arm-linux-androideabi-addr2line 工具定位 libunity.so 崩溃问题-程序员宅基地

文章浏览阅读710次,点赞13次,收藏7次。它的名称有点不同 - aarch64-linux-android-addr2line。尽管该实用程序的名称不包含单词arm,但它成功地解密了arm64-v8下的堆栈跟踪,并通常感知arm64-v8的字符。是 NDK 自带的调试工具,可以用来分析 so 崩溃时输出的的内存地址。之后就是通过 cmd 进入到这个路径。找到了 64 位所需的实用程序。_arm-linux-androideabi

javaweb-邮件发送_javaweb发送邮件-程序员宅基地

javaweb-邮件发送 摘要: 本文介绍了邮件传输协议(SMTP和POP3)以及电子邮件的发送和接收过程。还讨论了纯文本文件、带图片和附件的邮件发送方法,以及通过servlet方式注册邮箱和使用springboot框架发送邮件的实现。

element-ui table 设置表格滚动条位置_element table 滚动条位置-程序员宅基地

文章浏览阅读4.3k次,点赞6次,收藏11次。在切换不同页面时(被 keep-alive 缓存的组件间切换),页面中的element-ui table的滚动条位置没有停留在原来的位置。目前需要切换不同的页面返回来后,滚动条保持在原来的位置。_element table 滚动条位置

前端开发经验总结_属性值[session.getattribute("strpath")]引用["],在值内使用时必须-程序员宅基地

文章浏览阅读2.6k次。 我设置nowrap和不设置nowrap效果都一样。就是表格随着文字自动伸展,为什么? →回答问题:TD元素noWrap属性的行为与TD元素的width属性有关。 ◆如果未设置TD宽度,则noWrap属性是起作用的。◆如果设置了TD宽度,则noWrap属性是不起作用的。 http://www.blueidea.com/tech/web/2003/943.as_属性值[session.getattribute("strpath")]引用["],在值内使用时必须被转义。

JS如何把Object对象的数据输出到控制台中_前端怎么通过控制台查看字段取值-程序员宅基地

文章浏览阅读3.4k次,点赞2次,收藏3次。 前端时间在编写程序时遇到这样一个问题,即在前端页面通过一些js框架自带的异步请求返回的数据类型为Object数据类型,笔者根据网上查阅到的资料,找到以下这种简单的方式://把Object类型转为Json数据格式,再通过console命令在控制台中打印出来console.log("xhr的值为:"+JSON.st..._前端怎么通过控制台查看字段取值

8.cc.Button组件使用详解_cc button.start-程序员宅基地

文章浏览阅读556次。1. cc.Button添加按钮的方法 2种方式 (1)直接创建带Button组件的节点; (2) 先创建节点,再添加组件;按钮组件, 按钮是游戏中最常用的组件, 点击然后响应事件;按钮的过渡效果: 过渡: 普通状态, 鼠标滑动到物体上, 按下状态, 禁用状态 (1)没有过渡,只有响应事件; (2)颜色过渡, 过渡效果中使用颜色; (3)精灵..._cc button.start

随便推点

计算机专业游戏本推荐,2018高性价比游戏本推荐_游戏笔记本哪个好-太平洋电脑网...-程序员宅基地

文章浏览阅读245次。【PConline海选导购】晃眼间,秋风又起,让人振奋的开学季又要到来了!虽然说没有学习压力的暑假,在家着实悠哉,但想到回校后可以跟小伙伴们一起各种开黑吃鸡,是不是就感到很兴奋呢?说到“吃鸡”这种吃配置的游戏,就不得不说游戏本了,毕竟普通的笔记本电脑很难给我们带来畅快的游戏体验。而近年来游戏本市场俨然成为了各大厂商的必争之地,而随着开学季的到来,各大厂商更是推出了众多促销活动,下面就让我们一起来看..._计应专业游戏本

codePen按钮样式学习

看到codepen里面有的按钮搞得很炫酷,但其实也不是很难,就学习记录一下。

服务器维护中没法直播游戏,我的世界盒子显示维护中如何进入战堂服务器-程序员宅基地

文章浏览阅读408次。时间:2021-08-11编辑:hxh斗罗大陆魂师对决火雨队怎么搭配?火雨队是近期非常热门的一套阵容,不少玩家想了解该阵容,那么下面就让小编给大家带来斗罗大陆魂师对决火雨队阵容推荐,感兴趣的小伙伴们一起来看看吧。时间:2021-08-11编辑:hxh玩家在巅峰演武副本中不知道怎么打秦明,秦明的盾很厚不知道怎么破?那么下面就让小编给大家带来斗罗大陆魂师对决巅峰演武秦明破盾攻略,感兴趣的小伙伴们一起来...

GNU Radio之Schmidl & Cox OFDM synch.底层C++实现

在 GNU Radio OFDM 系统中,一个非常重要的环节是在接收端准确地同步和检测发送端发出的信号。这就是 Schmidl & Cox 同步算法发挥作用的地方。Schmidl & Cox 算法是一种用于 OFDM 信号的时间同步的技术。本文对其底层 C++ 源码进行学习记录。

项目开发规范

REST,表述性状态转换,他是一种软件架构风格使用URL定位资源,HTTP动词描述操作根据发出请求类型来区分操作此为风格,是约定方式,可以打破描述模块的功能通常使用复数,也就是加s的格式来描述,表示此类资源,而非单个资源。

3.8设计模式——State 状态模式(行为型)

允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类。