iOS 开发仿网易云音乐歌词海报



使用网易云音乐也是一个巧合,我之前一直使用QQ音乐听歌,前几天下 app 手机内存告急。于是就把QQ音乐给卸载掉了,正好晚上朋友圈里有一个朋友用网易云音乐分享了一首歌曲,于是我也就尝试下载了网易云音乐,这一下载就让我从QQ音乐粉转黑了。

从设计的角度来看,网易云音乐的界面简洁,慷慨,不像kugou音乐一打开就是各种广告。让人心烦。也不像QQ音乐那样动不动就各种音质,各种冲钻(不为用户需求考虑。仅仅想赚钱,差评)。最关键的是它推荐的歌真是好听,实在是太懂我了,真的是非常用心的在做音乐。

废话不多说了,今天给大家带来一篇山寨网易云音乐歌词海报生成的文章。自从发现了这个功能,我已经在朋友圈刷屏了。

既然这么喜欢,那为何不自己来实现一下呢!

首先,有些童鞋可能还不清楚什么是歌词海报,我在这里就先简单的作一个说明:我们在听歌的时候难免会有那么几句歌词在脑海中余音缭绕。网易云音乐就有这么一个功能,你能够查看你喜欢的歌词然后选中它们,然后App会将这些歌词附加到那些文艺的背景中去生成一张海报,这样你就能够将它分享到你的朋友圈里去,做一个装逼的文艺青年。

设计思路:

  1. 解析歌词文件,在界面上用UITableView载入
  2. 长按界面。将UITableView切换至可编辑状态
  3. 将选中的歌词保存
  4. 依据歌词的数量在UIImageView上动态创建UILabel
  5. 将UIImageView保存为图片存至相冊

代码实现:

眼下代码解析的歌词文件都是lrc的格式。比如网易。QQ。他们都有自己的海量的歌词数据,在网上搜索歌词文件也能搜索到非常多。比如次样式的:

[00:01.16] 不为谁而作的歌 - 林俊杰
[00:05.96] 词:林秋离
[00:08.16] 曲:林俊杰
[00:27.51] 原谅我这一首不为谁而作的歌
[00:34.12] 感觉上仿佛窗外的夜色
[00:41.24] 以前有那一刻
[00:44.18] 回头居然认不得须要从记忆再摸索的人
[00:54.85] 和他们关心的 的地方
[01:01.50] 和那些走过的请等一等
[01:10.55] 梦为努力浇了水

有了歌词文件还不行。我们得把歌词和时间都解析出来,这就要用到我们的歌词解析功能了,代码例如以下:

#import <Foundation/Foundation.h>

@interface LrcParseUtil : NSObject
//时间
@property (nonatomic,strong) NSMutableArray *timerArray;
//歌词
@property (nonatomic,strong) NSMutableArray *wordArray;

-(NSString *)getLrcFile:(NSString *)lrc;

//解析歌词
-(void) parseLrc:(NSString*)lrc;

@end
#import "LrcParseUtil.h"

@implementation LrcParseUtil
@synthesize timerArray = _timerArray;
@synthesize wordArray = _wordArray;

-(instancetype) init{
    self=[super init];
    if(self!=nil){
        self.timerArray=[[NSMutableArray alloc] init];
        self.wordArray=[[NSMutableArray alloc] init];
    }
    return  self;
}

-(NSString *)getLrcFile:(NSString *)lrc{
    NSString* filePath=[[NSBundle mainBundle] pathForResource:lrc ofType:@"lrc"];
    return  [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil];
}

-(void)parseLrc:(NSString *)lrc{
    if(![lrc isEqual:nil]){
        NSArray *sepArray=[lrc componentsSeparatedByString:@"["];
        NSArray *lineArray=[[NSArray alloc] init];
        for(int i=0;i<sepArray.count;i++){
            if([sepArray[i] length]>0){
                lineArray=[sepArray[i] componentsSeparatedByString:@"]"];
                if(![lineArray[0] isEqualToString:@"\n"]){
                    [self.timerArray addObject:lineArray[0]];
                    [self.wordArray addObject:lineArray.count>1?lineArray[1]:@""];
                }
            }
        }
    }
}

@end


上面我们仅仅是将歌词文件转化为数据存储到了我们的内存中,接下来要把这些数据显示给用户,这里我们就要用到UITableView这个强大的控件了,至于这个空间的使用我这里就不在阐述了,代码例如以下:

@interface ViewController ()

@end

@implementation ViewController
@synthesize lrcTableView = _lrcTableView;
@synthesize parseUtil = _parseUtil;
@synthesize selectLrcView = _selectLrcView;

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

    self.title = @"Silicon Demo";
    [self.view setBackgroundColor:[UIColor blackColor]];

    self.lrcTableView = [[UITableView alloc] initWithFrame:self.view.bounds];
    self.lrcTableView.delegate = self;
    self.lrcTableView.dataSource = self;

    [self.lrcTableView setBackgroundColor:[UIColor clearColor]];
    self.lrcTableView.separatorStyle = UITableViewCellSeparatorStyleNone;

    [self.view addSubview:self.lrcTableView];

    //解析歌词
    self.parseUtil = [[LrcParseUtil alloc] init];
    [self.parseUtil parseLrc:[self.parseUtil getLrcFile:@"demoSong"]];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

#pragma -mark tableview
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
    return 40.0f;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
    if(!self.selectLrcView){
        self.selectLrcView = [SelectLrcViewController new];
    }

    [self.selectLrcView setLrcData:self.parseUtil.wordArray];

    CATransition *animation = [CATransition animation];
    [animation setDuration:0.3];
    [animation setType: kCATransitionFade];
    [animation setSubtype: kCATransitionFromTop];
    [animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionDefault]];

    [self.navigationController pushViewController:self.selectLrcView animated:NO];
    [self.navigationController.view.layer addAnimation:animation forKey:nil];
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{

    return [self.parseUtil.wordArray count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    UITableViewCell *cell = [self.lrcTableView dequeueReusableCellWithIdentifier:@"cell"];
    if(!cell){
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cell"];
    }

    cell.textLabel.text = self.parseUtil.wordArray[indexPath.row];
    cell.textLabel.textColor = [UIColor whiteColor];
    cell.textLabel.textAlignment = NSTextAlignmentCenter;
    cell.textLabel.font = [UIFont systemFontOfSize:15];
    cell.backgroundColor=[UIColor clearColor];

    return cell;
}

@end

效果例如以下:



UITableView控件原生自带了选择功能,所以我这边图省力就先用原生自带的实现歌词选择功能(日后会更新成自己定义的), 代码例如以下:

#import "SelectLrcViewController.h"

@interface SelectLrcViewController ()

@end

@implementation SelectLrcViewController
@synthesize lrcWordsArray = _lrcWordsArray;
@synthesize wordsTableView = _wordsTableView;
@synthesize selectedLrcs = _selectedLrcs;

- (instancetype)init{
    self = [super init];

    self.lrcWordsArray = [[NSMutableArray alloc] init];
    self.selectedLrcs = [[NSMutableArray alloc] init];

    return self;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    NSLog(@"%@", self.navigationController.navigationBar);

    // Do any additional setup after loading the view.
    UIBarButtonItem *tempBarItem = [[UIBarButtonItem alloc] initWithTitle:@"生成图片" style:UIBarButtonItemStylePlain target:self action:@selector(generatePic)];

    self.navigationItem.rightBarButtonItem = tempBarItem;

    self.wordsTableView = [[UITableView alloc] initWithFrame:self.view.bounds];
    self.wordsTableView.delegate = self;
    self.wordsTableView.dataSource = self;
    [self.wordsTableView setBackgroundColor:[UIColor clearColor]];
    self.wordsTableView.separatorStyle = UITableViewCellSeparatorStyleNone;
    self.wordsTableView.editing = YES;
    self.wordsTableView.allowsMultipleSelectionDuringEditing = YES;

    [self.view addSubview:self.wordsTableView];
}

- (void)viewWillAppear:(BOOL)animated{
    [super viewWillAppear:animated];

    [self.wordsTableView reloadData];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.

}

- (void)setLrcData:(NSMutableArray *)lrcdata{
    self.lrcWordsArray = lrcdata;
}

- (void)generatePic{
    NSArray *selectIndex = [self.wordsTableView indexPathsForSelectedRows];
    if([selectIndex count] == 0 || !selectIndex){
        NSLog(@"请选择歌词");

        return;
    }

    [self.selectedLrcs removeAllObjects];

    for (int i = 0; i < [selectIndex count]; i++) {
        NSIndexPath *index = selectIndex[i];
        [self.selectedLrcs addObject:[self.lrcWordsArray objectAtIndex:index.row]];
    }

    if([self.selectedLrcs count] == 0){
        return;
    }

    if(!self.lrcShareView){
        self.lrcShareView = [LrcShareViewController new];
    }

    [self.lrcShareView setLrcContent:self.selectedLrcs];

    CATransition *animation = [CATransition animation];
    [animation setDuration:0.3];
    [animation setType: kCATransitionFade];
    [animation setSubtype: kCATransitionFromTop];
    [animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionDefault]];

    [self.navigationController pushViewController:self.lrcShareView animated:NO];
    [self.navigationController.view.layer addAnimation:animation forKey:nil];
}

#pragma -mark tableview
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
    return 40.0f;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
    NSLog(@"");
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
    return [self.lrcWordsArray count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    UITableViewCell *cell = [self.wordsTableView dequeueReusableCellWithIdentifier:@"cell"];
    if(!cell){
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cell"];
    }

    cell.textLabel.text = self.lrcWordsArray[indexPath.row];
    cell.textLabel.textColor = [UIColor whiteColor];
    cell.textLabel.textAlignment = NSTextAlignmentCenter;
    cell.textLabel.font = [UIFont systemFontOfSize:15];
    cell.backgroundColor=[UIColor clearColor];

    return cell;
}

效果例如以下:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvc2hlbmppZTEyMzQ1Njc4/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="这里写图片描写叙述" title="">



最后一步就是生成歌词海报了。考虑到图片资源对App安装包大小造成的影响,这里採用了对背景图片进行拉伸的办法,在iOS 5.0之前,我们用此API进行对图片的拉伸:

- (UIImage *)stretchableImageWithLeftCapWidth:(NSInteger)leftCapWidth topCapHeight:(NSInteger)topCapHeight;

往往会将拉伸的大小设置为1像素。然后保证其它的地方不变,这样纵使我们的控件大小再怎么改变,图片也不会出现拉伸的情况。

但这个API在iOS 5之后就被废弃了,在这里我们该用它iOS 6以后新出的AP对图进行拉伸:

- (UIImage *)resizableImageWithCapInsets:(UIEdgeInsets)capInsets resizingMode:(UIImageResizingMode)resizingMode

有人可能会问。为什么不用图形上下文的方式在背景图片上绘制文字,我之前已尝试过可是生成海报后的像素实在是令人捉急,于是就把这个思路给pass了;后来经过细致分析,通过在UIImageView中加入subView也就是UILabel,然后通过下面代码生成的海报达到的效果令人惬意。代码例如以下:

 UIGraphicsBeginImageContextWithOptions(self.imageView.bounds.size, YES, 0.0);
    [self.imageView.layer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage *bitmap = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

这里附上,生成海报的所有代码:

#import "LrcShareViewController.h"
#import "ConstantUtil.h"
@interface LrcShareViewController ()

@end

@implementation LrcShareViewController
@synthesize shareLrcs = _shareLrcs;
@synthesize imageView = _imageView;
@synthesize scrollView = _scrollView;
@synthesize paperLayer = _paperLayer;
@synthesize shareBtn = _shareBtn;
@synthesize saveBtn = _saveBtn;
@synthesize pane = _pane;

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.

    //set scrollView and share & save Btn
    _scrollView = [[UIScrollView alloc] initWithFrame:self.view.bounds];
    _scrollView.backgroundColor = [UIColor clearColor];
    _scrollView.delegate = self;
    _scrollView.contentSize = self.view.bounds.size;
    _scrollView.scrollEnabled = YES;
    [self.view addSubview:_scrollView];

    [self addShareAndSaveBtn];
}

- (void)viewWillAppear:(BOOL)animated{
    // init the imageView
    self.imageView = [UIImageView new];

    // resize the background image , adapte to the lrcs
    self.paperLayer = [self drawLrcsWithImageContext:[UIImage imageNamed:@"simple.png"]];
    [self.imageView setImage:self.paperLayer];

    //add labels on the imageView
    [self addLyricToBackground:self.shareLrcs];
    [self.scrollView addSubview:self.imageView];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

/*
 *@brief 加入分享与保存button
 */
- (void)addShareAndSaveBtn{
    self.pane = [[UIView alloc] initWithFrame:CGRectMake(0, self.view.bounds.size.height - 35.0f, self.view.bounds.size.width, 35.f)];
    [self.pane setBackgroundColor:[UIColor clearColor]];

    self.shareBtn = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width / 2, 35.0f)];
    [self.shareBtn setBackgroundColor:[UIColor colorWithRed:23.0f green:24.0f blue:24.0f alpha:0]];
    [self.shareBtn setTitle:@"分享" forState:UIControlStateNormal];
    [self.shareBtn setTintColor:[UIColor whiteColor]];
    [self.shareBtn addTarget:self action:@selector(socialCCshare) forControlEvents:UIControlEventTouchDown];

    self.saveBtn = [[UIButton alloc] initWithFrame:CGRectMake(self.view.bounds.size.width / 2 + 1, 0, self.view.bounds.size.width / 2, 35.0f)];
    [self.saveBtn setBackgroundColor:[UIColor colorWithRed:23.0f green:24.0f blue:24.0f alpha:0]];
    [self.saveBtn setTitle:@"保存" forState:UIControlStateNormal];
    [self.saveBtn setTintColor:[UIColor whiteColor]];
    [self.saveBtn addTarget:self action:@selector(saveToPhoto) forControlEvents:UIControlEventTouchDown];

    UIImageView *line = [[UIImageView alloc] initWithFrame:CGRectMake(self.view.bounds.size.width / 2, 0, 1, 35)];
    [line setBackgroundColor:[UIColor whiteColor]];

    [self.pane addSubview:self.shareBtn];
    [self.pane addSubview:self.saveBtn];
    [self.pane addSubview:line];
    [self.view addSubview:self.pane];
}

- (void)socialCCshare{
    NSLog(@"分享");
}

/*
 *@brief 保存至手机相冊
 */
- (void)saveToPhoto{
    UIGraphicsBeginImageContextWithOptions(self.imageView.bounds.size, YES, 0.0);
    [self.imageView.layer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage *bitmap = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    UIImageWriteToSavedPhotosAlbum(bitmap, self, @selector(image:didFinishSavingWithError:contextInfo:), NULL);
}

- (void)image: (UIImage *) image didFinishSavingWithError: (NSError *) error contextInfo: (void *) contextInfo
{
    NSString *msg = nil ;
    if(error != NULL){
        msg = @"保存图片失败" ;
    }else{
        msg = @"保存图片成功" ;
    }

    NSLog(@"%@", msg);
}

- (void)setLrcContent:(NSMutableArray *)selectLrcs{
    self.shareLrcs = selectLrcs;
}

/*
 *@brief 动态加入歌词到UIImageView
 *@param lrcsArray 歌词
 */
- (void)addLyricToBackground:(NSMutableArray *)lrcsArray{

    CGFloat point_x = 40.0f;
    CGFloat point_y = 50.0f;
    CGFloat t_per_size = 15.0f;
    CGFloat row_height = 20.0f;
    CGFloat margin = 10.0f;

    for(int i = 0; i < [lrcsArray count]; i++){
        //get lrc from array
        NSString *lrc = [lrcsArray objectAtIndex:i];
        int lrcLen = lrc.length;

        //create a label to show the lrc
        UILabel *lrcLabel = [[UILabel alloc] initWithFrame:CGRectMake(point_x, point_y + i * (row_height + margin), lrcLen * t_per_size, row_height)];

        [lrcLabel setText:lrc];
        lrcLabel.font = [UIFont fontWithName:@"Arial" size:15];
        lrcLabel.textColor = [UIColor lightGrayColor];
        [self.imageView addSubview:lrcLabel];
    }

    //note the song‘s name
    NSString *songName = @"── [不为谁而做的歌]";
    CGFloat y_songName = self.imageView.frame.size.height - 90.0f;
    CGFloat width_songName = self.imageView.frame.size.width - 80.0f;
    UILabel *songFrom = [[UILabel alloc] initWithFrame:CGRectMake((self.view.bounds.size.width - width_songName)/2, y_songName, width_songName, row_height)];
    [songFrom setText:songName];
    songFrom.font = [UIFont fontWithName:@"Arial" size:15];
    songFrom.textColor = [UIColor lightGrayColor];
    [songFrom setTextAlignment:NSTextAlignmentRight];
    [self.imageView addSubview:songFrom];
}

/*
 * @brief 拉伸背景图片达到满足背景的要求
 * @param layerImage 背景图片
 */
- (UIImage *)drawLrcsWithImageContext:(UIImage *)layerImage{
    CGFloat rowHeight = 20.0f;
    CGFloat margins = 5.0f;

    /*
     *背景海报的高度
     *header iphone 固定为80px
     *footer iphone 固定为120px
     */
    CGFloat imageHeight = (rowHeight + margins) * [self.shareLrcs count];
    //背景海报的宽度为屏幕固定宽度
    CGFloat imageWidth = self.view.bounds.size.width;

    [self.imageView setFrame:CGRectMake(0, 0, imageWidth, 200 + imageHeight)];

    CGFloat top = layerImage.size.height /2 - 1;
    CGFloat left = layerImage.size.width /2 - 1;
    CGFloat bottom = layerImage.size.height /2 - 1;
    CGFloat right = layerImage.size.width /2 - 1;

    // 设置端盖的值
    UIEdgeInsets edgeInsets = UIEdgeInsetsMake(top, left, bottom, right);
    // 设置拉伸的模式
    UIImageResizingMode mode = UIImageResizingModeStretch;
    // 拉伸图片
    UIImage *newImage = [layerImage resizableImageWithCapInsets:edgeInsets resizingMode:mode];

    return newImage;
}

@end

效果图例如以下:


总结

此功能在界面效果和用户体验上离网易还差非常远,可是主要的核心已经实现。当然实现这样的效果可能有100种方法。欢迎大家来指正。我也会继续更新代码像网易靠拢。

GitHub地址:https://github.com/ShenJieSuzhou/https—github.com-ShenJieSuzhou-LrcShareDemo.git



好了。

祝大家生活愉快。多多收获友谊和爱情。假设想获取很多其它的讯息,请扫描下方二维码关注我的微信公众号:

原文地址:https://www.cnblogs.com/zhchoutai/p/8452230.html

时间: 2024-10-17 11:36:35

iOS 开发仿网易云音乐歌词海报的相关文章

C# WPF 低仿网易云音乐(PC)歌词控件

原文:C# WPF 低仿网易云音乐(PC)歌词控件 提醒:本篇博客记录了修改的过程,废话比较多,需要项目源码和看演示效果的直接拉到文章最底部~ 网易云音乐获取歌词的api地址 http://music.163.com/api/song/media?id=歌曲ID 填写歌曲的id即可获取到json格式的数据(歌曲ID获取的方法是:点击分享按钮>其他分享>复制链接,就可以在链接中看到了): {"songStatus":0,"lyricVersion":10,

《云阅》一个仿网易云音乐UI,使用Gank.Io及豆瓣Api开发的开源项目

CloudReader 一款基于网易云音乐UI,使用GankIo及豆瓣api开发的符合Google Material Desgin阅读类的开源项目.项目采取的是Retrofit + RxJava + MVVM-DataBinding架构开发.开发中所遇到的各种问题已归纳在这里. github地址:CloudReader What can be learned about this project 那么,从本项目中你能学到哪些知识呢? 1.干货集中营内容与豆瓣电影书籍内容. 2.高仿网易云音乐歌单

Android实战之酷云--&gt;仿网易云音乐开发

我的个人网站 Xuejianxin's Blog Google Blog Xuejianxin's Blog Android自定义View学习 Android自定义View之常用工具源码分析 Android自定义View之onMeasure()源码分析 Android自定义View之onLayout()源码分析 Android自定义View之对TouchEvent的处理 Android自定义View之draw原理分析 如果觉得我的文章还行的话,也可以关注我的公众号,里面也会第一时间更新,并且会有

基于Taro与Typescript开发的网易云音乐小程序

基于Taro与网易云音乐api开发,技术栈主要是:typescript+taro+taro-ui+redux,目前主要是着重小程序端的展示,主要也是借此项目强化下上述几个技术栈的使用,通过这个项目也可以帮助你快速使用Taro开发一个属于你自己的小程序- 源码地址:taro-music,感兴趣的话可以star关注下,功能会进行持续完善 快速开始 首先需要在src目录下创建一个config.ts,可以根据自己的需要将其替换成线上地址,接口服务是使用的NeteaseCloudMusicApi expo

仿网易云音乐 专辑图片折叠轮播

仿网易云音乐 专辑图片折叠轮播 先不多说现上一张效果图 首先简述一下实现原理 1.首先让我们的imageview**动起来** 其实是不断的.invalidate();函数 让他不断的调用ondarw函数 (显然我们不必要不断的调用ondarw函数 只有在我们让他动的时候调用即可 所以我们要声明一个变量记录change记录是否产生动画) 2.实现我们的可折叠效果 Matrix的setPolyToPoly方法的使用 可参考(http://blog.csdn.net/lmj623565791/art

仿网易云音乐的播放进度条

仿网易云音乐的播放进度条,有三种状态:播放.暂停和拖动,只是实现了动画和主要的交互逻辑,其他细节(如暂停音乐的播放等)还需要自己完善: DKPlayerBar 是继承于UIControl的,如果想获取播放\暂停的事件建议用标准的addTarget方法: [playerBar addTarget:self action:@selector(playOrPause) forControlEvents:UIControlEventValueChanged]; 然后在DKPlayerBar里监听DKPl

高仿网易云音乐客户端的Home页面切换Tabhost-IT蓝豹

1.高仿网易云音乐客户端的Home页面切换Tabhost 高仿网易云音乐客户端的Home页面切换Tabhost,并且三角形是透明的,实现方式,自定义AnimTabsView继承 RelativeLayout 里面对当前选中的item 处理 三角形变成透明效果,即在onDraw 里面对三角形图片经行透明度处理,AnimTabsView提供 setOnAnimTabsItemViewChangeListener方法的onChange()用来监听点击切换tabhost. 下面主要是AnimTabsVi

如何用Python网络爬虫爬取网易云音乐歌词

前几天小编给大家分享了数据可视化分析,在文尾提及了网易云音乐歌词爬取,今天小编给大家分享网易云音乐歌词爬取方法. 本文的总体思路如下: 找到正确的URL,获取源码: 利用bs4解析源码,获取歌曲名和歌曲ID: 调用网易云歌曲API,获取歌词: 将歌词写入文件,并存入本地. 本文的目的是获取网易云音乐的歌词,并将歌词存入到本地文件.整体的效果图如下所示: 基于Python网易云音乐歌词爬取 赵雷的歌曲 本文以民谣歌神赵雷为数据采集对象,专门采集他的歌曲歌词,其他歌手的歌词采集方式可以类推,下图展示

一款网易云音乐歌词制作软件

软件作者 BensonLaur 文章原始地址:https://www.cnblogs.com/BensonLaur/p/6262565.html 软件很好用,谨在此作为个人备忘记录,以后需要的时候方便找. 软件最新下载地址:  请点击 →  (若提示 beslyric.320.io 的花生壳流量又没流量了,则可使用下面备用地址下载) 解压后直接运行里面exe文件即可. 点击 备用地址1  地址2  地址3 下载 Question:程序提示“手动下载 ffmpeg.exe 文件”,怎么下载? 点击