ionic2 + 按名字分组的手机通讯录 组件

Posted final-elysion

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ionic2 + 按名字分组的手机通讯录 组件相关的知识,希望对你有一定的参考价值。

ionic2 名字分组手机通讯录 组件

实现以下功能

  • 获取手机通讯录数据
  • 数据分组显示(中文英文正确分组)
  • 点击索引进行跳转
  • 滚动到特殊位置进行特别处理
  • 联系人查询

预览

技术分享图片

contacts.html

<ion-header>
  <ion-navbar>
    <ion-title>选择联系人</ion-title>
  </ion-navbar>
</ion-header>

<ion-content padding>
 <ion-searchbar [debounce]="searchDebounce" [(ngModel)]="searchKey" 
  [showCancelButton]="shouldShowCancel" 
  (ionInput)="onInput($event)" (ionCancel)="onCancel($event)">
  </ion-searchbar>
<ion-row style="height: 88%">
   
  <ion-col col-11 >
    <!-- <div *ngIf="!contactList||contactList.length<=0">
      <div >手机通讯录没有联系人</div>
    </div> -->
    <ion-scroll #scroll scrollY="true" style="height: 100%">
        <ion-item-group *ngFor="let contactItem of contactList" >
          <ion-item-divider color="light" id="index_{{contactItem.letter}}">
            {{contactItem.letter}}
          </ion-item-divider>

          <ion-item *ngFor="let contact of contactItem.contact" (click)="selectContact(contact)">
           <!--  <ion-avatar item-start>
              <img src="assets/icon/favicon.ico">
            </ion-avatar> -->
            <h2> {{contact.displayName}}</h2>
            <p>手机:{{contact.phoneNumbers[0].value}}</p>
          </ion-item>
        </ion-item-group>
    </ion-scroll>
  </ion-col>
  <ion-col col-1 class="index-num">
    <div  *ngFor="let indexItem of contactIndex" (click)="goToIndex(indexItem)">{{indexItem}}</div>
  </ion-col>
</ion-row>
 

</ion-content>

contacts.scss

.index-num{
  color:blue;
    font-size: 13px;
}

.scroll-content{
  padding:0px !important
}

.red-index{
  color:red;
}

contacts.component.ts

import { Component, ViewChild } from '@angular/core';
import { NavController, NavParams } from 'ionic-angular';
import { Contacts } from '@ionic-native/Contacts';
import { CommonUtil } from '../common.util';

@Component({
  selector: 'contacts',
  templateUrl: 'contacts.html'
})

/**
  联系人组件
  @author 0o晓月メ
*/
export class ContactsComponent {
  @ViewChild('scroll') scroll: any;
  private contactList: any;
  private contactIndex: Array<string>;
  private searchKey: string;
  private shouldShowCancel: boolean;
  public isCordova: boolean;
  public searchDebounce: number = 600;
  public currentId:string;
  private isios:boolean;
  constructor(private commonUtil: CommonUtil, private contacts: Contacts, public navCtrl: NavController, public navParams: NavParams) {
    this.initData();
  }
  /**
    滚动到特定位置做特殊处理 demo
  */
  ngAfterViewInit() {
    if(!this.isCordova){
      this.scroll.addScrollEventListener((event) => {
        let positionN = document.getElementById('index_' + 'N').offsetTop;
        let positionS = document.getElementById('index_' + 'S').offsetTop;
        if (event.currentTarget.scrollTop > positionN && event.currentTarget.scrollTop < positionS) {
          console.log('在模块N');
          this.currentId ='N';
        } else if (event.currentTarget.scrollTop > positionS) {
          console.log('在模块S');
          this.currentId ='S';
        } else {
          this.currentId ='';
          console.log('还没到达N模块');
        }
      });
    }
  }

  initData(): void {
    this.searchKey = "";
    this.shouldShowCancel = true;
    this.isCordova = this.commonUtil.isCordova();
    this.isIOS = this.commonUtil.isIOS();
    this.contactIndex = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split('');
    //alert(  .isCordova)
    if (this.isCordova) {
      let opts = {
        filter: "",
        multiple: true,
        hasPhoneNumber: true,
        fields: ['displayName', 'name']
      };
      let me = this;
      this.contacts.find(['displayName', 'name'], opts)
        .then((contactList) => {
          me.contactList = contactList;
          console.log(contactList)
          me.generateContactGroup(contactList);
        }, (error) => {
          console.log(error);
        });
    } else {
      let data = this.initBrowserData();
      this.generateContactGroup(data);
    }

  }
  /**
    调用callback方法传送选择的联系信息,再跳回上一个页面

    demo:
    this.navCtrl.push(ContactComponent,{callback:this.callBackTest,scope:this});
    
    callBackTest(param):Promise<any>{
      let me = this;
      return new Promise(resolve => {
        me.recommendPhone = param.phoneNumbers[0].value;;
        console.log(me.recommendPhone);
        resolve('success');
      })
    }
  */

  selectContact(contact): void {
    if (!contact) contact = null;
    let callback = this.navParams.get("callback");
    let scope = this.navParams.get("scope");
    if (!callback || !scope) {
      alert('Callback function or scope is not provide!');
      return;
    }
    callback.call(scope, contact).then(() => {
      this.navCtrl.pop();
    });
  }

  onInput($event): void {
    console.log($event);
    if (this.isCordova) {
      let opts = {
        filter: this.searchKey,
        multiple: true,
        hasPhoneNumber: true,
        fields: ['displayName', 'name']
      };

      this.contacts.find(['displayName', 'name'], opts)
        .then((contactList) => {
          this.contactList = contactList;
          console.log(contactList)
          this.generateContactGroup(contactList);
        }, (error) => {
          console.log(error);
        });
    } else {
      let data = this.initBrowserData();
      this.generateContactGroup(data);
    }
  }

  onCancel($event): void {

  }

  /**
    联系人分组
  */
  generateContactGroup(arr) {
    if (!String.prototype.localeCompare) {
      console.error('localeCompare function not found');
      return [];
    }

    //enTmp cnArray
    let enResult = this.sortEnContacts(arr);
    console.log('generateContactGroup=>enResult', enResult);

    let sortResult = enResult.enTmp;
    let cnArray = enResult.cnArray;
    let enKey = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split('');
    let letters = "*abcdefghjklmnopqrstwxyz".split('');
    let zh = "阿八嚓哒妸发旮哈讥咔垃痳拏噢妑七呥扨它穵夕丫帀".split('');

    for (let i = 0; i < letters.length; i++) {
      let letter = letters[i].toUpperCase();
      let curr;
      if (sortResult[letter]) {
        curr = sortResult[letter];
      } else if ('*' != letters[i]) {
        curr = sortResult[letter] = [];
      }

      for (var j = 0; j < cnArray.length; j++) {
        if ((!zh[i - 1] || zh[i - 1].localeCompare(cnArray[j].displayName,'zh') <= 0) && cnArray[j].displayName.localeCompare(zh[i],'zh') == -1) {
          curr.push(cnArray[j]);
        }
      }
    }

    let contactResult = [];

    for (let k = 0; k < enKey.length; k++) {
      let item = sortResult[enKey[k]];
      if (item && item.length > 0)
        contactResult.push({ letter: enKey[k], contact: item });
    }
    console.log(contactResult);
    this.contactList = contactResult;
    return contactResult;
  }

  /**
    联系人英文名字先分组
  */
  sortEnContacts(contactList: Array<any>) {
    let en = ['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'];
    let enTmp = {};
    let cnArray = [];
    for (var i = 0; i < contactList.length; i++) {
      if( this.isIOS && this.isCordova){
        contactList[i].displayName =  contactList[i].name.formatted;
      }
      let letter = contactList[i].displayName.toUpperCase().charAt(0);
      if (en.indexOf(letter) >= 0) {
        if (enTmp[letter] == undefined) {
          enTmp[letter] = []
        }
        enTmp[letter].push(contactList[i]);
      } else {
        cnArray.push(contactList[i])
      }
    }
    return { 'enTmp': enTmp, 'cnArray': cnArray };
  }


  goToIndex(letter): void {
    console.log(letter);
    let target = document.getElementById('index_' + letter);
    if (target)
      this.scroll._scrollContent.nativeElement.scrollTop = target.offsetTop;
  }

  initBrowserData(): Array<any> {
    return [{ displayName: 'jack', phoneNumbers: [{ value: "13626578952" }] },
    { displayName: '陈先生', phoneNumbers: [{ value: "13626578952" }] },
    { displayName: '吴先生', phoneNumbers: [{ value: "13626578952" }] },
    { displayName: '王先生', phoneNumbers: [{ value: "13626578952" }] },
    { displayName: '林小姐', phoneNumbers: [{ value: "13626578952" }] },
    { displayName: '冯先生', phoneNumbers: [{ value: "13626578952" }] },
    { displayName: '蒋生', phoneNumbers: [{ value: "13626578952" }] },
    { displayName: '黄生', phoneNumbers: [{ value: "13626578952" }] },
    { displayName: 'jack', phoneNumbers: [{ value: "13626578952" }] },
    { displayName: 'mike', phoneNumbers: [{ value: "13626578952" }] },
    { displayName: 'ivin', phoneNumbers: [{ value: "13626578952" }] },
    { displayName: 'kevin', phoneNumbers: [{ value: "13626578952" }] },
    { displayName: '谁', phoneNumbers: [{ value: "13626578952" }] },
    { displayName: '张小姐', phoneNumbers: [{ value: "13626578952" }] },
    { displayName: '好', phoneNumbers: [{ value: "13626578952" }] },
    { displayName: 'tag', phoneNumbers: [{ value: "13626578952" }] },
    { displayName: 'ok', phoneNumbers: [{ value: "13626578952" }] },
    { displayName: 'jack', phoneNumbers: [{ value: "13626578952" }] },
    { displayName: 'fary', phoneNumbers: [{ value: "13626578952" }] },
    { displayName: 'note', phoneNumbers: [{ value: "13626578952" }] },
    { displayName: 'may', phoneNumbers: [{ value: "13626578952" }] },
    { displayName: 'moon', phoneNumbers: [{ value: "13626578952" }] },
    { displayName: '月', phoneNumbers: [{ value: "13626578952" }] },
    { displayName: '辉', phoneNumbers: [{ value: "13626578952" }] },
    { displayName: '明', phoneNumbers: [{ value: "13626578952" }] },
    { displayName: '郭生', phoneNumbers: [{ value: "13626578952" }] },
    { displayName: 'kity', phoneNumbers: [{ value: "13626578952" }] },
    { displayName: 'marry', phoneNumbers: [{ value: "13626578952" }] },
    ];
  }
}

以上是关于ionic2 + 按名字分组的手机通讯录 组件的主要内容,如果未能解决你的问题,请参考以下文章

小程序超实用组件:仿微信通讯录

怎样实现Android手机通讯录的分组(代码实现)

微信通讯录下面的#分组是啥意思

QQ通讯录(Android)如何增加分组?

C语言制作通讯录怎么将联系人的名字按26个字母的顺序排序

怎么让苹果手机里的通讯录按字母顺序排