android表白app

一、前言

  马上就要520和521了,是不是还有像我一样的单身狗啊。我就知道有,所以这两天简单写了这个小程序(其实是替别人写的),虽然我并不会用去骗女孩子(因为最近太忙了,实习完之后要搞毕设,要搞论文啊,谁能帮帮我...),但是我想很多人肯定会感兴趣吧。如果你感兴趣就拿去逗妹子一乐吧。

  如果你很感兴趣,你可以在我写的基础上增辉加彩,或者根据我提供的资源自己动手,尝试一下。

二、先show一下效果

   

 

三、Android手机如何录制屏幕及转GIF

  https://www.aswifter.com/2015/07/10/android-record-video-to-gif/

  

  第一次试的时候没有成功,第二次设定屏幕分辨率后成功了,但是效果太差。果断又试了第三次,成功了,手机根目录出现了刚刚录制的视屏文件。

  adb pull 会把文件从手机上复制到本地(ANDROID_SDK_HOME/platform-tools目录下,也就是adb.exe所在的目录)

  接着就是转换成gif了,这里我用PS处理

  

    

   然后文件——》存储为web所有格式——》选择gif。如果gif过大,可能会导致ps崩溃,简单的做法就是调整图片的大小,就可以了。

四、下载地址

  apk文件:https://github.com/hjzgg/LoveDemo/tree/master/bin

  项目:https://github.com/hjzgg/LoveDemo

五、技术路线,分享我的制作过程

1.准备

  大二的时候搞过一段时间的android,时隔一年半,好多东西都忘了,不过现在捡起来也不晚。

  开发工具使用eclipse或者android studio。我使用的eclipse,那么就要自己去安装ADT和SDK了,安装的时间有点蛋疼啊。

2.资源收集

  作为一个表白程序,必须要有图片吧,文字吧, 最好加上背景音乐吧,不然就真的没有意思了。下面分享几个资源链接:

  文字特效: https://github.com/elevenetc/TextSurface

  图片切花特效: https://github.com/daimajia/AndroidImageSlider

  音乐播放器: http://www.cnblogs.com/TerryBlog/archive/2010/06/26/1765910.html

  

  先说一下文字特效,将文字特效的代码下载下来后,所有的演示代码放在了\app\src\main\java\su\levenetc\android\textsurface\sample\checks这里面,app\src\main\java\su\levenetc\android\textsurface\sample\SampleActivity.java是app入口activity。最主要的代码放在了library目录下,需要将library\src\main下面的文件复制到我们的项目中,参考入口activity的内容进行调用就可以了。 资源中提供了很多文字展示的效果,本人愚钝,只用了两个,而且用的不是太好。我主要增加了文字处理,效果结合的功能。将要展示的文字按照4句划分,然后调用文字效果展示。文字资源放在了assets文件夹下面。

  图片切换特效很好用,进本不要改动,直接把图片换了就行了,效果不错。

  音乐播放器引用网上的一位哥们儿的,写的简介靠谱,这里直接拿来用了,用的是MediaPlayer进行音乐播放。我改了一些地方,里面有点儿小bug。增加了一个功能,就是在sd卡不存在的时候(无论是内置的还是外置的),依然可以获取到音乐文件,考虑了好多方式,比如直接调用网上的,或者调用手机内存中的...,想了想还是将音乐文件放在项目当中了,可以放在res/raw下,也可以放在assets下,各有好处,本人放在了res/raw目录下。还有一个要注意的是判断手机的sd卡环境是否可以使用。具体的还是看代码吧。

3.主要代码

  说了这么多,最主要的代码都是在一个activity中,代码如下:

  MainActivity.java

public class MainActivity extends ListActivity implements BaseSliderView.OnSliderClickListener{@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);//初始化图片切换
        initChangePicture();//初始化音乐
        initMusic();//初始化文字展示
        initWord();}@Overridepublic void onSliderClick(BaseSliderView slider) {Toast.makeText(this, slider.getBundle().get("extra") + "",Toast.LENGTH_SHORT).show();}private SliderLayout mDemoSlider;private void initChangePicture(){mDemoSlider = (SliderLayout)findViewById(R.id.slider);//两种方式加载数据//加载本地HashMap<String,String> url_maps = new HashMap<String, String>();url_maps.put("GitOnWay", "http://gitonway.blog.163.com/");//加载网络HashMap<String,Integer> file_maps = new HashMap<String, Integer>();file_maps.put("love-A",R.drawable.a);file_maps.put("love-B",R.drawable.b);file_maps.put("love-C",R.drawable.c);file_maps.put("love-D", R.drawable.d);for(String name : file_maps.keySet()){TextSliderView textSliderView = new TextSliderView(this);// 初始化幻灯片页面
             textSliderView.description(name).image(file_maps.get(name)).setOnSliderClickListener(this);//添加要传递的数据
             textSliderView.getBundle().putString("extra",name);mDemoSlider.addSlider(textSliderView);}//       幻灯片切换方式  
         mDemoSlider.setPresetTransformer(SliderLayout.Transformer.Accordion);
//       指示符位置  
         mDemoSlider.setPresetIndicator(SliderLayout.PresetIndicators.Center_Bottom);
//       定义指示器样式  
//       mDemoSlider.setCustomIndicator(your view);
//       幻灯片循环  
//       mDemoSlider.startAutoCycle();
//       停止循环
         mDemoSlider.stopAutoCycle();
//       设置指示器的显示与否  
         mDemoSlider.setIndicatorVisibility(PagerIndicator.IndicatorVisibility.Visible);
//       设置幻灯片的转化时间  
//       mDemoSlider.setSliderTransformDuration(5000, null);
//       用来自定义幻灯片标题的显示方式  mDemoSlider.setCustomAnimation(new DescriptionAnimation());
//       幻灯片切换时间  mDemoSlider.setDuration(3000);//         实现随机切换TimerTask task = new TimerTask() {@Overridepublic void run() {Transformer[] tranformers = SliderLayout.Transformer.values();Transformer transformer = tranformers[(int) (Math.random() * tranformers.length)];mDemoSlider.setPresetTransformer(transformer);}};new Timer().schedule(task, 2000, 2000);}//res/raw中的音乐文件资源映射private Map<String, Integer> musicPath;//播放对象private MediaPlayer myMediaPlayer;//播放列表private List<String> myMusicList = new ArrayList<String>();//当前播放歌曲的索引private int currentListItem=0;//音乐的路径, 如果存在sd卡,则使用sd卡,否则使用内存中的data目录private static String MUSIC_PATH = hasSDCardMounted() ?  new String(Environment.getExternalStorageDirectory().getAbsolutePath() + "/hjz/"): null;private void initMusic(){myMediaPlayer=new MediaPlayer();findView();musicList();listener();//自动播放第一首歌if(myMusicList.size() > 0){playMusic(MUSIC_PATH, myMusicList.get(currentListItem));}}public static boolean hasSDCardMounted() {String state = Environment.getExternalStorageState();if (state != null && state.equals(Environment.MEDIA_MOUNTED)) {return true;} else {return false;}}//绑定音乐private void musicList(){try {File home = new File(MUSIC_PATH);//如果有sd卡,但是sd卡中没有指定的音乐文件夹,则采用项目中的音乐文件if(MUSIC_PATH == null || home.listFiles() == null) {//绑定 res/raw下的音乐文件MUSIC_PATH = null;musicPath = new HashMap<String, Integer>();musicPath.put("杨宗纬 - 一次就好.mp3", R.raw.yi_ci_jiu_hao);musicPath.put("霍建华,赵丽颖 - 不可说.mp3", R.raw.bu_ke_shuo);musicPath.put("川井憲次 - 孤独な巡礼.mp3", R.raw.gu_du_xun_li);myMusicList.addAll(musicPath.keySet());} else {Log.v("MUSIC_PATH", MUSIC_PATH);if(home.listFiles(new MusicFilter()).length>0){for(File file:home.listFiles(new MusicFilter())){myMusicList.add(file.getName());}}}if(myMusicList.size() > 0) {ArrayAdapter<String> musicList = new ArrayAdapter<String>(MainActivity.this, R.layout.musicitme, myMusicList);setListAdapter(musicList);}} catch (Exception e) {Log.e("获取音乐文件出错:", e.toString());}}//获取按钮void findView(){viewHolder.start=(Button)findViewById(R.id.start);viewHolder.stop=(Button)findViewById(R.id.stop);viewHolder.next=(Button)findViewById(R.id.next);viewHolder.pause=(Button)findViewById(R.id.pause);viewHolder.last=(Button)findViewById(R.id.last);}//监听事件void listener(){//停止viewHolder.stop.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stubif(myMediaPlayer.isPlaying()){myMediaPlayer.reset();}}});//开始viewHolder.start.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {if(myMusicList.size() == 0) return;playMusic(MUSIC_PATH, myMusicList.get(currentListItem));}});//下一首viewHolder.next.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {nextMusic();}});//暂停viewHolder.pause.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {if(myMusicList.size() == 0) return;if(myMediaPlayer.isPlaying()){myMediaPlayer.pause();}else{myMediaPlayer.start();}}});//上一首viewHolder.last.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {lastMusic();}});}//播放音乐 void playMusic(String basePath, String path){try { if(basePath != null) {myMediaPlayer.reset();myMediaPlayer.setDataSource(basePath+path);myMediaPlayer.prepare();} else {myMediaPlayer.pause();myMediaPlayer.release();myMediaPlayer = MediaPlayer.create(MainActivity.this, musicPath.get(path));}myMediaPlayer.start();myMediaPlayer.setOnCompletionListener(new OnCompletionListener() {@Overridepublic void onCompletion(MediaPlayer mp) {nextMusic();}});} catch (Exception e) {Log.e("播放sd卡音乐失败", e.toString());e.printStackTrace();}}//下一首void nextMusic(){if(myMusicList.size() > 0) {if(++currentListItem>=myMusicList.size()){currentListItem=0;}playMusic(MUSIC_PATH, myMusicList.get(currentListItem));}}//上一首void lastMusic(){if(myMusicList.size() > 0) {if(currentListItem!=0) {playMusic(MUSIC_PATH, myMusicList.get(--currentListItem));}  else{playMusic(MUSIC_PATH, myMusicList.get(currentListItem=myMusicList.size()-1));}}}//当用户返回时结束音乐并释放音乐对象
       @Overridepublic boolean onKeyDown(int keyCode, KeyEvent event) {if(keyCode==KeyEvent.KEYCODE_BACK){myMediaPlayer.stop();myMediaPlayer.release();this.finish();return true;}return super.onKeyDown(keyCode, event);}//当选择列表项时播放音乐 
    @Overrideprotected void onListItemClick(ListView l, View v, int position, long id) {currentListItem=position;playMusic(MUSIC_PATH, myMusicList.get(currentListItem));}//初始化文字展示private TextSurface textSurface;private void initWord(){LinearLayout layout = (LinearLayout) findViewById(R.id.LinearLayoutWord);//找到你要设透明背景的layout 的id layout.getBackground().setAlpha(60);//0~255透明度值 textSurface = (TextSurface) findViewById(R.id.text_surface);textSurface.postDelayed(new Runnable() {@Override public void run() {show();}}, 1000);}private void show() {textSurface.reset();List<AnimationsSet> animationsSets = new ArrayList<AnimationsSet>();animationsSets.add(CookieThumperSample.getCookieThumperAnimations(getAssets()));animationsSets.addAll(SlideSample.getSlideAnimations(getContents()));textSurface.play(TYPE.SEQUENTIAL, animationsSets.toArray(new AnimationsSet[]{}));//        ColorSample.play(textSurface);
//        AlignSample.play(textSurface);
//        Rotation3DSample.play(textSurface);
//        ScaleTextSample.run(textSurface);
//        ShapeRevealLoopSample.play(textSurface);
//        ShapeRevealSample.play(textSurface);
//        SlideSample.play(textSurface);
//        SurfaceScaleSample.play(textSurface);
//        SurfaceTransSample.play(textSurface);
    }private List<String> getContents(){List<String> contents = new ArrayList<String>();try{   //得到资源中的asset数据流  String fileName = "content.txt"; //文件名字   String res="";   InputStream in = getResources().getAssets().open(fileName);   int length = in.available();           byte [] buffer = new byte[length];          in.read(buffer);              in.close();  res = EncodingUtils.getString(buffer, "UTF-8");String[] strings = res.split("[,|,|\\.|。]");int len = strings.length/4 * 4;for(int i=0; i < len; ++i)contents.add(strings[i]);}catch(Exception e){   e.printStackTrace();Log.e("getContents", e.toString());}   return contents;}
}

  activity_main.xml(页面布局)

<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"xmlns:custom="http://schemas.android.com/apk/res-auto"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"tools:context="com.gitonway.androidimagesliderdemo.activity.MainActivity"><LinearLayout android:id="@+id/LinearLayoutPicture"android:orientation="vertical"android:layout_weight="3"android:layout_height="fill_parent"android:layout_width="match_parent"><!-- 图片切换  --><com.gitonway.androidimagesliderdemo.widget.imageslider.SliderLayoutandroid:id="@+id/slider"android:layout_width="match_parent"android:layout_height="fill_parent"custom:pager_animation="Accordion"custom:auto_cycle="true"custom:indicator_visibility="visible"custom:pager_animation_span="1100"/><!--  <com.gitonway.androidimagesliderdemo.widget.imageslider.Indicators.PagerIndicatorandroid:id="@+id/custom_indicator"android:layout_width="wrap_content"android:layout_height="wrap_content"android:gravity="center"custom:selected_color="#0095BF"custom:unselected_color="#55333333"custom:selected_drawable="@drawable/ic_launcher"custom:shape="oval"custom:selected_padding_left="6dp"custom:selected_padding_right="6dp"custom:unselected_padding_left="2dp"custom:unselected_padding_right="2dp"android:layout_centerHorizontal="true"android:layout_alignParentBottom="true"custom:selected_width="6dp"custom:selected_height="6dp"custom:unselected_width="6dp"custom:unselected_height="6dp"android:layout_marginBottom="20dp"/><com.gitonway.androidimagesliderdemo.widget.imageslider.Indicators.PagerIndicatorandroid:id="@+id/custom_indicator2"style="@style/AndroidImageSlider_Corner_Oval_Orange"android:layout_centerHorizontal="true"android:layout_alignParentBottom="true"android:layout_marginBottom="20dp"/>  --></LinearLayout><!-- 文字展现  --><LinearLayout android:id="@+id/LinearLayoutWord"android:layout_weight="3"android:layout_height="fill_parent"android:orientation="vertical"android:background="@android:color/background_dark"android:layout_width="match_parent"><com.textsurface.TextSurfaceandroid:id="@+id/text_surface"android:layout_height="fill_parent"android:layout_width="match_parent"/></LinearLayout><!-- 音乐播放器  --><LinearLayoutandroid:id="@+id/LinearLayoutMusic"android:layout_width="match_parent"android:layout_weight="4"android:layout_height="fill_parent"android:orientation="vertical" ><ListViewandroid:id="@id/android:list"android:layout_width="match_parent"android:layout_weight="1"android:layout_height="fill_parent"android:scrollbars="vertical" /><LinearLayoutandroid:id="@+id/bottomBtn"android:layout_width="match_parent"android:layout_height="60dp"android:gravity="center|center_horizontal|center_vertical"android:orientation="horizontal" ><Button   android:id="@+id/last"  android:background="@drawable/last"android:layout_width="wrap_content" android:layout_height="wrap_content"></Button><Button  android:id="@+id/stop"android:background="@drawable/stop"android:layout_marginLeft="10dp"android:layout_width="wrap_content" android:layout_height="wrap_content"></Button><Button  android:id="@+id/start" android:background="@drawable/start"android:layout_marginLeft="10dp"android:layout_width="wrap_content" android:layout_height="wrap_content"></Button><Button  android:id="@+id/pause" android:layout_width="wrap_content"android:background="@drawable/pause"android:layout_marginLeft="10dp"android:layout_height="wrap_content"></Button><Button  android:id="@+id/next"android:background="@drawable/next"android:layout_marginLeft="10dp"android:layout_width="wrap_content" android:layout_height="wrap_content"></Button></LinearLayout></LinearLayout></LinearLayout>

 

  

转载于:https://www.cnblogs.com/hujunzheng/p/5510151.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/531313.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

c语言:malloc函数的简介

文章目录一、为什么需要malloc函数&#xff1f;二、如何使用malloc函数&#xff1f;三、用malloc函数自定义数组长度一、为什么需要malloc函数&#xff1f; 用于解决传统数组以下缺点。 ①传统数组的长度必须要事先指定。 ②传统数组的内存无法手动释放。 ③传统数组的长度定义…

webpack+react+es6开发模式

一、前言 实习了两个月&#xff0c;把在公司用到的前端开发模式做个简单的整理。公司里前端开发模式webpackreactreduxes6&#xff0c;这里去掉了redux。 webpack, react, redux等学习网址&#xff1a;http://www.cnblogs.com/hujunzheng/p/5405780.html 二、简单的步骤条组件 …

c语言输入字符时控制符%c前加空格的原因解释

文章目录一、前景知识1、缓冲区2、标准输入流二、scanf语句的执行1、scanf对于整形%d的输入2、scanf对于字符%c的输入在编一个代码时偶然间发现一个知识盲点…用scanf语句输入字符时需要在控制符%c前加空格。在解释相关这个原因前我们需要了解几个相关知识点。 一、前景知识 1…

git命令分类图

转载于:https://www.cnblogs.com/hujunzheng/p/5560826.html

python中为什么没有自增或者自减

在c语言和c中我们经常会用到自增或者自减的语句&#xff0c;但对于python中如果运用这种格式便会报错…why&#xff1f; 一、预备知识 小整数池 python中为了提高储存效率&#xff0c;对于int类型的整型变量的储存&#xff0c;有一个专门的小整数池&#xff0c;它会存放-5到256…

数据结构算法模拟系统

一、前言 学习数据结构已经有很长时间了&#xff0c;加上之前搞过一段时间的ACM&#xff0c;虽然搞得并不怎么样吧&#xff0c;但是喜欢的东西不能放弃&#xff0c;一直打算写一个算法模拟系统&#xff0c;对常用的一些算法进行简单的模拟&#xff0c;于是我的毕业设计就这样诞…

python语言map函数及map object at 乱码错误

文章目录一、map函数的简介1、map函数的作用2、语法格式3、举例例1、例2、二、报错一、map函数的简介 1、map函数的作用 对某个序列以给定的函数格式作映射。 2、语法格式 map(function,iterable)   function可以填函数&#xff0c;也可以填数据类型 3、举例 例1、 a [1,2,…

推荐几款jquery图片切换插件

一、前言 毕业季到了&#xff0c;大家都在匆匆忙忙的记录大学里最美好的时光&#xff0c;照片中各种花式、各种姿势都涌现出来了。这么多的照片怎么展示出来给自己的好友看呢&#xff1f;有人选择做成视频&#xff0c;有人选择ps之后做成图片集&#xff0c;而我选择利用静态网页…

c语言表白

马上就要520了&#xff0c;不少小伙伴们一定开始想尽各种办法进行表白了…那么身为奔跑在程序员道路上的我们也一定要有独特的表白方法&#xff01; 下面是一段表白代码&#xff0c;请直接搬去用吧&#xff01;&#xff01;&#xff01; #include <stdio.h> void change…

java注意的一些细节问题

1. 大括弧作用域问题 public static void main(String[] args) {{int x;{int x;//编译错误&#xff1a;Duplicate local variable x}} } 2.boolean值的运算 public static void main(String[] args) {if(true && false) {}if(true & false) {}System.out.println(t…

python表白

马上就要520了&#xff0c;不少小伙伴们一定开始想尽各种办法进行表白了…那么身为奔跑在程序员道路上的我们也一定要有独特的表白方法&#xff01; 下面是一段表白代码&#xff0c;请直接搬去用吧&#xff01;&#xff01;&#xff01; import turtle import timedef hart_ar…

git revert和reset区别

1.在github上建立测试项目并克隆到本地 2.本地中新建两个文本文件 3.将a.txt commit并push到远程仓库 执行 git add a.txt, git commit -m "a.txt", git push 4.将b.txt提交到本地仓库&#xff0c;不执行push 通过gitk命令查看提交历史如下&#xff1a; 情景&#xf…

python基础知识点整理(1)

目录一、变量与数据类型1、变量① 变量的命名规则2、字符串常用的库函数二、列表1、列表的基础定义2、列表常用的库函数3、for循环与列表4、列表切片5、元组三、if语句四、字典1、字典定义2、对字典的操作一、变量与数据类型 1、变量 ① 变量的命名规则 只能包含数字、字母以…

sorl6.0+jetty+mysql搭建solr服务

1.下载solr 官网&#xff1a;http://lucene.apache.org/solr/ 2.目录结构如下 3.启动solr&#xff08;默认使用jetty部署&#xff09; 在path路径下将 bin文件夹对应的目录加入&#xff0c;然后输入 solr start&#xff08;或者 solr start -p port&#xff0c;指定端口启动&am…

Maven中安装本地Jar包到仓库中或将本地jar包上传

摘要 maven install 本地jar命令格式 mvn install:install-file -DgroupId<group_name> -DartifactId<artifact_name> -Dversion<version_no> -Dfile<path_of_the_local_jar> -Dpackagingjar -DgeneratePomtrue 示例 mvn install:install-file -Dgroup…

二维码登录原理及生成与解析

一、前言 这几天在研究二维码的扫码登录。初来乍到&#xff0c;还有好多东西不懂。在网上看到有人写了一些通过QRCode或者Zxing实现二维码的生成和解码。一时兴起&#xff0c;决定自己亲手试一试。本人是通过QRCode实现的&#xff0c;下面具体的说一下。 二、二维码原理 基础知…

knockout+echarts实现图表展示

一、需要学习的知识 knockout, require, director, echarts, jquery。简单的入一下门&#xff0c;网上的资料很多&#xff0c;最直接就是进官网校习。 二、效果展示 三、require的配置 require.config.js中可以配置我们的自定义模块的加载。 require.config({baseUrl: ".&…

Maven在Eclipse中的实用小技巧

前言 我们在开发的工程中很多都是Maven项目&#xff0c;这样更加便于我们jar包的管理。而我们一般使用的IDE都是Eclipse&#xff0c;由于我们在日常的开发过程中会经常要用到一些Maven的操作&#xff0c;所以我今天主要跟大家分享一下我们在日常开发中的Maven实用小知识&#x…

React中使用Ant Table组件

一、Ant Design of React http://ant.design/docs/react/introduce 二、建立webpack工程 webpackreact demo下载 项目的启动&#xff0c;参考 三、简单配置 1.工程下载下来之后&#xff0c;在src目录下新建目录“table”&#xff0c;新建app.js&#xff0c;内容如下。 import R…

解决“Dynamic Web Module 3.0 requires Java 1.6 or newer.”错误

一、问题描述 1.错误截图如下。 2.设计的问题 在Eclipse中新建了一个Maven工程, 然后更改JDK版本为1.6, 结果每次使用Maven > Update project的时候JDK版本都恢复成1.5。 二、原因分析 Maven官方文档有如下描述&#xff1a; 编译器插件用来编译项目的源文件.从3.0版本开始, …