一、前言

  马上就要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

  1. public class MainActivity extends ListActivity implements BaseSliderView.OnSliderClickListener{
  2.  
  3. @Override
  4. protected void onCreate(Bundle savedInstanceState) {
  5. super.onCreate(savedInstanceState);
  6. setContentView(R.layout.activity_main);
  7.  
  8. //初始化图片切换
  9. initChangePicture();
  10. //初始化音乐
  11. initMusic();
  12. //初始化文字展示
  13. initWord();
  14. }
  15.  
  16. @Override
  17. public void onSliderClick(BaseSliderView slider) {
  18. Toast.makeText(this, slider.getBundle().get("extra") + "",Toast.LENGTH_SHORT).show();
  19. }
  20.  
  21. private SliderLayout mDemoSlider;
  22. private void initChangePicture(){
  23. mDemoSlider = (SliderLayout)findViewById(R.id.slider);
  24.  
  25. //两种方式加载数据
  26.  
  27. //加载本地
  28. HashMap<String,String> url_maps = new HashMap<String, String>();
  29. url_maps.put("GitOnWay", "http://gitonway.blog.163.com/");
  30.  
  31. //加载网络
  32. HashMap<String,Integer> file_maps = new HashMap<String, Integer>();
  33. file_maps.put("love-A",R.drawable.a);
  34. file_maps.put("love-B",R.drawable.b);
  35. file_maps.put("love-C",R.drawable.c);
  36. file_maps.put("love-D", R.drawable.d);
  37.  
  38. for(String name : file_maps.keySet()){
  39. TextSliderView textSliderView = new TextSliderView(this);
  40. // 初始化幻灯片页面
  41. textSliderView
  42. .description(name)
  43. .image(file_maps.get(name))
  44. .setOnSliderClickListener(this);
  45.  
  46. //添加要传递的数据
  47. textSliderView.getBundle()
  48. .putString("extra",name);
  49.  
  50. mDemoSlider.addSlider(textSliderView);
  51. }
  52.  
  53. // 幻灯片切换方式
  54. mDemoSlider.setPresetTransformer(SliderLayout.Transformer.Accordion);
  55. // 指示符位置
  56. mDemoSlider.setPresetIndicator(SliderLayout.PresetIndicators.Center_Bottom);
  57. // 定义指示器样式
  58. // mDemoSlider.setCustomIndicator(your view);
  59. // 幻灯片循环
  60. // mDemoSlider.startAutoCycle();
  61. // 停止循环
  62. mDemoSlider.stopAutoCycle();
  63. // 设置指示器的显示与否
  64. mDemoSlider.setIndicatorVisibility(PagerIndicator.IndicatorVisibility.Visible);
  65. // 设置幻灯片的转化时间
  66. // mDemoSlider.setSliderTransformDuration(5000, null);
  67. // 用来自定义幻灯片标题的显示方式
  68. mDemoSlider.setCustomAnimation(new DescriptionAnimation());
  69. // 幻灯片切换时间
  70. mDemoSlider.setDuration(3000);
  71.  
  72. // 实现随机切换
  73. TimerTask task = new TimerTask() {
  74. @Override
  75. public void run() {
  76. Transformer[] tranformers = SliderLayout.Transformer.values();
  77. Transformer transformer = tranformers[(int) (Math.random() * tranformers.length)];
  78. mDemoSlider.setPresetTransformer(transformer);
  79. }
  80. };
  81.  
  82. new Timer().schedule(task, 2000, 2000);
  83. }
  84.  
  85. //res/raw中的音乐文件资源映射
  86. private Map<String, Integer> musicPath;
  87. //播放对象
  88. private MediaPlayer myMediaPlayer;
  89. //播放列表
  90. private List<String> myMusicList = new ArrayList<String>();
  91. //当前播放歌曲的索引
  92. private int currentListItem=0;
  93. //音乐的路径, 如果存在sd卡,则使用sd卡,否则使用内存中的data目录
  94. private static String MUSIC_PATH = hasSDCardMounted() ? new String(Environment.getExternalStorageDirectory().getAbsolutePath() + "/hjz/")
  95. : null;
  96.  
  97. private void initMusic(){
  98. myMediaPlayer=new MediaPlayer();
  99. findView();
  100. musicList();
  101. listener();
  102.  
  103. //自动播放第一首歌
  104. if(myMusicList.size() > 0){
  105. playMusic(MUSIC_PATH, myMusicList.get(currentListItem));
  106. }
  107. }
  108.  
  109. public static boolean hasSDCardMounted() {
  110. String state = Environment.getExternalStorageState();
  111. if (state != null && state.equals(Environment.MEDIA_MOUNTED)) {
  112. return true;
  113. } else {
  114. return false;
  115. }
  116. }
  117.  
  118. //绑定音乐
  119. private void musicList(){
  120. try {
  121. File home = new File(MUSIC_PATH);
  122. //如果有sd卡,但是sd卡中没有指定的音乐文件夹,则采用项目中的音乐文件
  123. if(MUSIC_PATH == null || home.listFiles() == null) {//绑定 res/raw下的音乐文件
  124. MUSIC_PATH = null;
  125. musicPath = new HashMap<String, Integer>();
  126. musicPath.put("杨宗纬 - 一次就好.mp3", R.raw.yi_ci_jiu_hao);
  127. musicPath.put("霍建华,赵丽颖 - 不可说.mp3", R.raw.bu_ke_shuo);
  128. musicPath.put("川井憲次 - 孤独な巡礼.mp3", R.raw.gu_du_xun_li);
  129. myMusicList.addAll(musicPath.keySet());
  130. } else {
  131. Log.v("MUSIC_PATH", MUSIC_PATH);
  132. if(home.listFiles(new MusicFilter()).length>0){
  133. for(File file:home.listFiles(new MusicFilter())){
  134. myMusicList.add(file.getName());
  135. }
  136. }
  137. }
  138. if(myMusicList.size() > 0) {
  139. ArrayAdapter<String> musicList = new ArrayAdapter<String>(MainActivity.this, R.layout.musicitme, myMusicList);
  140. setListAdapter(musicList);
  141. }
  142. } catch (Exception e) {
  143. Log.e("获取音乐文件出错:", e.toString());
  144. }
  145. }
  146.  
  147. //获取按钮
  148. void findView(){
  149. viewHolder.start=(Button)findViewById(R.id.start);
  150. viewHolder.stop=(Button)findViewById(R.id.stop);
  151. viewHolder.next=(Button)findViewById(R.id.next);
  152. viewHolder.pause=(Button)findViewById(R.id.pause);
  153. viewHolder.last=(Button)findViewById(R.id.last);
  154. }
  155.  
  156. //监听事件
  157. void listener(){
  158. //停止
  159. viewHolder.stop.setOnClickListener(new OnClickListener() {
  160.  
  161. @Override
  162. public void onClick(View v) {
  163. // TODO Auto-generated method stub
  164. if(myMediaPlayer.isPlaying()){
  165. myMediaPlayer.reset();
  166. }
  167. }
  168. });
  169. //开始
  170. viewHolder.start.setOnClickListener(new OnClickListener() {
  171.  
  172. @Override
  173. public void onClick(View v) {
  174. if(myMusicList.size() == 0) return;
  175. playMusic(MUSIC_PATH, myMusicList.get(currentListItem));
  176. }
  177. });
  178. //下一首
  179. viewHolder.next.setOnClickListener(new OnClickListener() {
  180.  
  181. @Override
  182. public void onClick(View v) {
  183. nextMusic();
  184. }
  185. });
  186. //暂停
  187. viewHolder.pause.setOnClickListener(new OnClickListener() {
  188.  
  189. @Override
  190. public void onClick(View v) {
  191. if(myMusicList.size() == 0) return;
  192. if(myMediaPlayer.isPlaying()){
  193. myMediaPlayer.pause();
  194. }else{
  195. myMediaPlayer.start();
  196. }
  197. }
  198. });
  199. //上一首
  200. viewHolder.last.setOnClickListener(new OnClickListener() {
  201. @Override
  202. public void onClick(View v) {
  203. lastMusic();
  204. }
  205. });
  206.  
  207. }
  208.  
  209. //播放音乐
  210. void playMusic(String basePath, String path){
  211. try {
  212. if(basePath != null) {
  213. myMediaPlayer.reset();
  214. myMediaPlayer.setDataSource(basePath+path);
  215. myMediaPlayer.prepare();
  216. } else {
  217. myMediaPlayer.pause();
  218. myMediaPlayer.release();
  219. myMediaPlayer = MediaPlayer.create(MainActivity.this, musicPath.get(path));
  220. }
  221. myMediaPlayer.start();
  222. myMediaPlayer.setOnCompletionListener(new OnCompletionListener() {
  223. @Override
  224. public void onCompletion(MediaPlayer mp) {
  225. nextMusic();
  226. }
  227. });
  228. } catch (Exception e) {
  229. Log.e("播放sd卡音乐失败", e.toString());
  230. e.printStackTrace();
  231. }
  232. }
  233.  
  234. //下一首
  235. void nextMusic(){
  236. if(myMusicList.size() > 0) {
  237. if(++currentListItem>=myMusicList.size()){
  238. currentListItem=0;
  239. }
  240. playMusic(MUSIC_PATH, myMusicList.get(currentListItem));
  241. }
  242. }
  243.  
  244. //上一首
  245. void lastMusic(){
  246. if(myMusicList.size() > 0) {
  247. if(currentListItem!=0) {
  248. playMusic(MUSIC_PATH, myMusicList.get(--currentListItem));
  249. } else{
  250. playMusic(MUSIC_PATH, myMusicList.get(currentListItem=myMusicList.size()-1));
  251. }
  252. }
  253. }
  254.  
  255. //当用户返回时结束音乐并释放音乐对象
  256. @Override
  257. public boolean onKeyDown(int keyCode, KeyEvent event) {
  258. if(keyCode==KeyEvent.KEYCODE_BACK){
  259. myMediaPlayer.stop();
  260. myMediaPlayer.release();
  261. this.finish();
  262. return true;
  263. }
  264. return super.onKeyDown(keyCode, event);
  265. }
  266.  
  267. //当选择列表项时播放音乐
  268. @Override
  269. protected void onListItemClick(ListView l, View v, int position, long id) {
  270. currentListItem=position;
  271. playMusic(MUSIC_PATH, myMusicList.get(currentListItem));
  272. }
  273.  
  274. //初始化文字展示
  275. private TextSurface textSurface;
  276. private void initWord(){
  277. LinearLayout layout = (LinearLayout) findViewById(R.id.LinearLayoutWord);//找到你要设透明背景的layout 的id
  278. layout.getBackground().setAlpha(60);//0~255透明度值
  279. textSurface = (TextSurface) findViewById(R.id.text_surface);
  280. textSurface.postDelayed(new Runnable() {
  281. @Override public void run() {
  282. show();
  283. }
  284. }, 1000);
  285. }
  286.  
  287. private void show() {
  288. textSurface.reset();
  289. List<AnimationsSet> animationsSets = new ArrayList<AnimationsSet>();
  290. animationsSets.add(CookieThumperSample.getCookieThumperAnimations(getAssets()));
  291. animationsSets.addAll(SlideSample.getSlideAnimations(getContents()));
  292. textSurface.play(TYPE.SEQUENTIAL, animationsSets.toArray(new AnimationsSet[]{}));
  293.  
  294. // ColorSample.play(textSurface);
  295. // AlignSample.play(textSurface);
  296. // Rotation3DSample.play(textSurface);
  297. // ScaleTextSample.run(textSurface);
  298. // ShapeRevealLoopSample.play(textSurface);
  299. // ShapeRevealSample.play(textSurface);
  300. // SlideSample.play(textSurface);
  301. // SurfaceScaleSample.play(textSurface);
  302. // SurfaceTransSample.play(textSurface);
  303. }
  304.  
  305. private List<String> getContents(){
  306. List<String> contents = new ArrayList<String>();
  307. try{
  308. //得到资源中的asset数据流
  309. String fileName = "content.txt"; //文件名字
  310. String res="";
  311. InputStream in = getResources().getAssets().open(fileName);
  312. int length = in.available();
  313. byte [] buffer = new byte[length];
  314. in.read(buffer);
  315. in.close();
  316. res = EncodingUtils.getString(buffer, "UTF-8");
  317. String[] strings = res.split("[,|,|\\.|。]");
  318. int len = strings.length/4 * 4;
  319. for(int i=0; i < len; ++i)
  320. contents.add(strings[i]);
  321. }catch(Exception e){
  322. e.printStackTrace();
  323. Log.e("getContents", e.toString());
  324. }
  325. return contents;
  326. }
  327. }

  activity_main.xml(页面布局)

  1. <LinearLayout
  2. xmlns:android="http://schemas.android.com/apk/res/android"
  3. xmlns:tools="http://schemas.android.com/tools"
  4. xmlns:custom="http://schemas.android.com/apk/res-auto"
  5. android:layout_width="match_parent"
  6. android:layout_height="match_parent"
  7. android:orientation="vertical"
  8. tools:context="com.gitonway.androidimagesliderdemo.activity.MainActivity">
  9.  
  10. <LinearLayout android:id="@+id/LinearLayoutPicture"
  11. android:orientation="vertical"
  12. android:layout_weight="3"
  13. android:layout_height="fill_parent"
  14. android:layout_width="match_parent">
  15. <!-- 图片切换 -->
  16. <com.gitonway.androidimagesliderdemo.widget.imageslider.SliderLayout
  17. android:id="@+id/slider"
  18. android:layout_width="match_parent"
  19. android:layout_height="fill_parent"
  20. custom:pager_animation="Accordion"
  21. custom:auto_cycle="true"
  22. custom:indicator_visibility="visible"
  23. custom:pager_animation_span="1100"/>
  24.  
  25. <!-- <com.gitonway.androidimagesliderdemo.widget.imageslider.Indicators.PagerIndicator
  26. android:id="@+id/custom_indicator"
  27. android:layout_width="wrap_content"
  28. android:layout_height="wrap_content"
  29. android:gravity="center"
  30. custom:selected_color="#0095BF"
  31. custom:unselected_color="#55333333"
  32. custom:selected_drawable="@drawable/ic_launcher"
  33. custom:shape="oval"
  34. custom:selected_padding_left="6dp"
  35. custom:selected_padding_right="6dp"
  36. custom:unselected_padding_left="2dp"
  37. custom:unselected_padding_right="2dp"
  38. android:layout_centerHorizontal="true"
  39. android:layout_alignParentBottom="true"
  40. custom:selected_width="6dp"
  41. custom:selected_height="6dp"
  42. custom:unselected_width="6dp"
  43. custom:unselected_height="6dp"
  44. android:layout_marginBottom="20dp"
  45. />
  46. <com.gitonway.androidimagesliderdemo.widget.imageslider.Indicators.PagerIndicator
  47. android:id="@+id/custom_indicator2"
  48. style="@style/AndroidImageSlider_Corner_Oval_Orange"
  49. android:layout_centerHorizontal="true"
  50. android:layout_alignParentBottom="true"
  51. android:layout_marginBottom="20dp"
  52. /> -->
  53. </LinearLayout>
  54.  
  55. <!-- 文字展现 -->
  56. <LinearLayout android:id="@+id/LinearLayoutWord"
  57. android:layout_weight="3"
  58. android:layout_height="fill_parent"
  59. android:orientation="vertical"
  60. android:background="@android:color/background_dark"
  61. android:layout_width="match_parent">
  62.  
  63. <com.textsurface.TextSurface
  64. android:id="@+id/text_surface"
  65. android:layout_height="fill_parent"
  66. android:layout_width="match_parent"/>
  67.  
  68. </LinearLayout>
  69.  
  70. <!-- 音乐播放器 -->
  71.  
  72. <LinearLayout
  73. android:id="@+id/LinearLayoutMusic"
  74. android:layout_width="match_parent"
  75. android:layout_weight="4"
  76. android:layout_height="fill_parent"
  77. android:orientation="vertical" >
  78.  
  79. <ListView
  80. android:id="@id/android:list"
  81. android:layout_width="match_parent"
  82. android:layout_weight="1"
  83. android:layout_height="fill_parent"
  84. android:scrollbars="vertical" />
  85.  
  86. <LinearLayout
  87. android:id="@+id/bottomBtn"
  88. android:layout_width="match_parent"
  89. android:layout_height="60dp"
  90. android:gravity="center|center_horizontal|center_vertical"
  91. android:orientation="horizontal" >
  92.  
  93. <Button android:id="@+id/last"
  94. android:background="@drawable/last"
  95. android:layout_width="wrap_content" android:layout_height="wrap_content"></Button>
  96.  
  97. <Button android:id="@+id/stop"
  98. android:background="@drawable/stop"
  99. android:layout_marginLeft="10dp"
  100. android:layout_width="wrap_content" android:layout_height="wrap_content"></Button>
  101.  
  102. <Button android:id="@+id/start"
  103. android:background="@drawable/start"
  104. android:layout_marginLeft="10dp"
  105. android:layout_width="wrap_content" android:layout_height="wrap_content"></Button>
  106.  
  107. <Button android:id="@+id/pause" android:layout_width="wrap_content"
  108. android:background="@drawable/pause"
  109. android:layout_marginLeft="10dp"
  110. android:layout_height="wrap_content"></Button>
  111.  
  112. <Button android:id="@+id/next"
  113. android:background="@drawable/next"
  114. android:layout_marginLeft="10dp"
  115. android:layout_width="wrap_content" android:layout_height="wrap_content"></Button>
  116. </LinearLayout>
  117. </LinearLayout>
  118.  
  119. </LinearLayout>

  

android表白app的更多相关文章

  1. 轻松搞定表白女朋友:Android版APP (零基础也可直接下载软件)

    在我们平时生活当中,经常会看到一些表白女朋友的html网页,但是Android端的表白软件可以说是基本没有,笔者在全网搜了一下,就没有一个可以用的.安卓端可以给人一种定制和精美的感觉,这是网页所做不到 ...

  2. 关于高校表白App的NABCD项目分析

    N(Need,需求) 首先,针对本校男多女少 的具体情况,为广大本校大学生提供一个更加宽广的平台: 其次,针对当前各高校均有校园表白墙的实际情况,各表白墙难以整合在一起,使得信息不够集中的现状,我们小 ...

  3. Cordova 打包 Android release app 过程详解

    Cordova 打包 Android release app 过程详解 时间 -- :: SegmentFault 原文 https://segmentfault.com/a/119000000517 ...

  4. 【Android端 APP GPU过度绘制】GPU过度绘制及优化

    一.Android端的卡顿 Android端APP在具体使用的过程中容易出现卡顿的情况,比如查看页面时出现一顿一顿的感受,切换tab之后响应很慢,或者具体滑动操作的时候也很慢. 二.卡顿的原因 卡顿的 ...

  5. 分享我开发的网络电话Android手机APP正式版,图文详解及下载

    分享我开发的网络电话Android手机APP正式版,图文详解及下载 分享我开发的网络电话Android手机APP正式版 实时语音通讯,可广域网实时通讯,音质清晰流畅! 安装之后的运行效果: 第一次安装 ...

  6. Android开发App工程结构搭建

    本文算是一篇漫谈,谈一谈关于android开发中工程初始化的时候如何在初期我们就能搭建一个好的架构.      关于android架构,因为手机的限制,目前我觉得也确实没什么大谈特谈的,但是从开发的角 ...

  7. Android 启动APP黑屏解决方案

    #Android 启动APP黑屏解决方案# 1.自定义Theme //1.设置背景图Theme <style name="Theme.AppStartLoad" parent ...

  8. Android手机app启动的时候第一个Activity必须是MainActivity吗

    原文:Android手机app启动的时候第一个Activity必须是MainActivity吗 Android手机APP启动的第一个Activity是可以自己设置的,不是必须的MainActivity ...

  9. Android原生APP内分享

    Android原生APP内分享,可实现数据分享以及assets文件夹分享及私有文件分享 项目地址:https://github.com/json-pu/AndroidAppShare.git

随机推荐

  1. MD5加密的Java实现

    在各种应用系统中,如果需要设置账户,那么就会涉及到储存用户账户信息的问题,为了保证所储存账户信息的安全,通常会采用MD5加密的方式来,进行储存.首先,简单得介绍一下,什么是MD5加密. MD5的全称是 ...

  2. HTML解析器HtmlAgilityPack的一些使用总结(C#)

    哎~本来这些总结是作为使用时的快速备注,但是用不上了.实际应用当中HtmlAgilityPack的可靠性不太稳定,一主要问题是:-> 一些字符会出现乱码或者变成'?',如韩语字符.由于我是已经有 ...

  3. Lession1 写在机器学习之前

    机器学习从学习方式上来讲,可以分为两类: 监督学习(Supervised Learning),简而言之就是“有标签”学习 无监督学习(Unsupervised Learning),简而言之就是“无标签 ...

  4. swift-闭包(代码块)

    语法 通用的语法 {(parameters) -> return type in statements } e.g let studname = { println("Welcome ...

  5. 踏上Salesforce的学习之路(一)

    相信通过前面的学习,大家已经拥有了一个属于自己的Salesforce开发者账号,下面,我们将用这个账号正式踏上Salesforce的学习之路. 首先,点击网址:https://developer.sa ...

  6. win7 x64 vs2010 directShow开发环境配置

    近来工作需要,要用dirrectShow写一个视频播放的demo验证自己的想法.开发环境配置了好久都没有成功,最后终于弄完,现在记录下来,以后有同学遇到同样问题,可以以此法解决. windows SD ...

  7. JavaScript 作用域知识点梳理

    JavaScript的作用域一直以来是前端开发中难以理解的知识点,对于JavaScript的作用域主要记住几句话. 一.“JavaScript” 中无块级作用域 在   Java 或 C# 中存在块级 ...

  8. 第三方框架之ThinkAndroid 学习总结(一)

    ThinkAndroid是一个免费的开源的.简易的.遵循Apache2开源协议发布的Android开发框架,其开发宗旨是简单.快速的进行Android应用程序的开发,包含Android mvc.简易s ...

  9. 更加精确的定时器:dispatch_source_t

    在使用定时器时,我们经常使用NSTimer,但是由于NSTimer会受RunLoop影响,当RunLoop处理的任务很多时,就会导致NSTimer的精度降低,所以在一些对定时器精度要求很高的情况下,应 ...

  10. 安卓学习之--UI控件用法 单选 按钮 下拉框

    1.单选 .RadioGroup 可将各自不同的RadioButton ,设限于同一个Radio 按钮组,同一个RadioGroup 组里的按钮,只能做出单一选择(单选题). <RadioGro ...