Android中设置TextView的行间距例子
一段文字,如果行间距很小的话看着就会很不舒服,我们在使用word文档的时候行间距是可以自己调整的,那么在Android开发的过程中如果一大段很长的文字如何设置行间距呢,很简单只需要一行代码:
android:lineSpacingExtra="3dp"
分享三张效果图:
第一张,没有设置行间距的,使用系统默认的效果:
第三张,设置为10dp的效果,更明显:
在使用QQ的过程中我们会发现一个很短的界面也是可以上下拖动的,这就是带有阻尼效果功能实现,要实现这样的功能呢,系统的ScrollView是没法实现的,必须要自定义继承于ScrollView的控件,先来看下效果图。
先来看看布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<frame.zmit.cn.stretchscrollview.StretchScrollView
android:id="@+id/scroll_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#E6E6E6"
android:orientation="vertical" >
<TextView
android:layout_width="match_parent"
android:layout_height="50dp"
android:textSize="16sp"
android:background="#FFFFFF"
android:gravity="center"
android:text="5" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#E6E6E6" />
<TextView
android:layout_width="match_parent"
android:layout_height="50dp"
android:textSize="16sp"
android:background="#FFFFFF"
android:gravity="center"
android:text="5" />
</LinearLayout>
</frame.zmit.cn.stretchscrollview.StretchScrollView>
</LinearLayout>
Activity啥也没有,就不贴了
下面贴上自定义的StretchScrollView
package frame.zmit.cn.stretchscrollview;
import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ScrollView;
/**
* A ScrollView which can scroll to (0,0) when pull down or up.
*
* @author markmjw
* @date 2014-04-30
*/
public class StretchScrollView extends ScrollView {
private static final int MSG_REST_POSITION = 0x01;
/** The max scroll height. */
private static final int MAX_SCROLL_HEIGHT = 600;
/** Damping, the smaller the greater the resistance */
private static final float SCROLL_RATIO = 0.4f;
private View mChildRootView;
private float mTouchY;
private boolean mTouchStop = false;
private int mScrollY = 0;
private int mScrollDy = 0;
private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
if (MSG_REST_POSITION == msg.what) {
if (mScrollY != 0 && mTouchStop) {
mScrollY -= mScrollDy;
if ((mScrollDy < 0 && mScrollY > 0) || (mScrollDy > 0 && mScrollY < 0)) {
mScrollY = 0;
}
mChildRootView.scrollTo(0, mScrollY);
// continue scroll after 20ms
sendEmptyMessageDelayed(MSG_REST_POSITION, 20);
}
}
}
};
public StretchScrollView(Context context) {
super(context);
init();
}
public StretchScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public StretchScrollView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
private void init() {
// set scroll mode
setOverScrollMode(OVER_SCROLL_NEVER);
}
@Override
protected void onFinishInflate() {
if (getChildCount() > 0) {
// when finished inflating from layout xml, get the first child view
mChildRootView = getChildAt(0);
}
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
mTouchY = ev.getY();
}
return super.onInterceptTouchEvent(ev);
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
if (null != mChildRootView) {
doTouchEvent(ev);
}
return super.onTouchEvent(ev);
}
private void doTouchEvent(MotionEvent ev) {
int action = ev.getAction();
switch (action) {
case MotionEvent.ACTION_UP:
mScrollY = mChildRootView.getScrollY();
if (mScrollY != 0) {
mTouchStop = true;
mScrollDy = (int) (mScrollY / 10.0f);
mHandler.sendEmptyMessage(MSG_REST_POSITION);
}
break;
case MotionEvent.ACTION_MOVE:
float nowY = ev.getY();
int deltaY = (int) (mTouchY - nowY);
mTouchY = nowY;
if (isNeedMove()) {
int offset = mChildRootView.getScrollY();
if (offset < MAX_SCROLL_HEIGHT && offset > -MAX_SCROLL_HEIGHT) {
mChildRootView.scrollBy(0, (int) (deltaY * SCROLL_RATIO));
mTouchStop = false;
}
}
break;
default:
break;
}
}
private boolean isNeedMove() {
int viewHeight = mChildRootView.getMeasuredHeight();
int scrollHeight = getHeight();
int offset = viewHeight - scrollHeight;
int scrollY = getScrollY();
return scrollY == 0 || scrollY == offset;
}
}
Acache类下载地址:http://pan.baidu.com/s/1gfI0A9X
1、创建Acache实例
Acache acache;
acache = Acache.get(this, “main”);
2、将数据保存起来(内存和文件)
acache.put(key,value,time);
前两个无需赘述,键值对,最后一个time,传入int类型,单位为秒,代表缓存存在的时间,超出这个时间,就会清除掉缓存的数据。
3、获取缓存的数据
以一个例子来描述这个问题:
代码如下 | 复制代码 |
public class MainActivity extends Activity { |
当我第一次进入的时候,控制台打印如下:
当我立即退出又进去,打印如下:
当我延迟了十秒左右再进去,又提示如下:
这样可以证明缓存可用,并且缓存的时间也有效果。
关于Android实现倒计时呢,对于很多人来说一直是一个头疼的问题,当然我也一样,在开发倒计时功能的时候会遇到很多棘手甚至奇葩的问题或者bug,我在开发倒计时的时候,如果当前页面只有一个倒计时,那么就不是很复杂,开发出来的效果也不是会非常糟糕,网上会有很多的教程实现。如果要在ListView或者GridView中实现倒计时呢,真的是一个很头疼的问题,我在这其中吃了很多苦头和走了很多弯路,还有死了很多脑细胞。下面我来总结一下在ListView中开发倒计时的问题。
先来展示一下我开发出来的效果图,这是在GridView中实现的:
一:数据混乱
描述一下什么叫数据混乱,比如说我有二十个倒计时在运行,第一个已经结束了,其他的都没有结束,我在往下滑动的时候,发现下面的某些倒计时也已经结束了,再循环滑动,又有不同的倒计时结束了,然后有时候本来已经结束的倒计时又开始倒计时了,这些就是在滑动过程中引发的数据混乱的问题。
二:倒计时重新开始:
描述一下什么叫倒计时重新开始,比如我的listview的第一个item在进行倒计时,从60秒开始减少,当减少到假如说40秒的时候,我往下滑动,使第一个item超出屏幕可见之外,再往上滑回第一个item,这时候你会发现倒计时又开始从60秒重新开始倒计时了,这是因为你的倒计时的时间如果是死的,在滑动回来的时候界面重绘,数据重新加载,所以倒计时又开始重新倒计时。
三:卡顿,超时,甚至崩溃:
这个就不用描述了,倒计时很多的话,就会出现卡顿的情况,如果非常多,手机就会死机崩溃,我在下载其他知名APP存在倒计时的界面进行使用时,一直上拉加载更多数据,出现很多的倒计时,发现也会卡顿,最后界面不能操作死机了。
四:倒计时不易控制和判断:
既然进行倒计时,那么我们就得需要监听倒计时什么时候结束,结束之后进行相应的操作,这是其一。其二,我们需要灵活的使用倒计时,比如是显示“年”、“天”、“时”、“分”、“秒”、“毫秒”等等,都要比较好控制和修改最好。
要解决这些问题呢,其实是很困难的,我查过很多的方式来实现发现都不是很好,甚至不能解决问题。最后呢,我找到了一个第三方依赖库,在github上也有,具体地址我找不到了,不过在it蓝豹上也有,这
在使用这个方式实现倒计时的时候,只解决了第三和第四的问题,说实话卡顿和控制方面解决了就好多了。另外我在使用的时候发现也会出现第一和第二个问题,当然在他的项目里也有在listview中的Demo,不过有点复杂我就没有深度研究,按照最基本的继承BaseAdapter和ViewHolder优化实现的方式来开发会出现数据错乱和重新开始的bug,最后我就在想能不能把倒计时时间来转化成本地时间进行倒计时,最后的结果是完全可以,不过可能会有一点误差,神奇的是连同数据混乱的bug也消失了。
比如说倒计时需要100秒,那么我就拿本地的时间加上这100秒作为结束时间,然后在倒计时需要开始的时候,拿上这结束时间减去本地时间就是需要倒计时的时间。
具体的代码如下:
具体的代码如下:
本地时间:long curTime = System.currentTimeMillis();//注意:单位毫秒
结束时间:curTime +(100*1000);//注意:单位毫秒,把100秒转化为毫秒
在需要倒计时的地方开启倒计时:
cv_countdownView.start(itemData.getEndtime() - System.currentTimeMillis());
同时,在监听方面,此依赖提供了一个接口:
代码如下:
cv_countdownView.setOnCountdownEndListener(new CountdownView.OnCountdownEndListener() {
@Override public void onEnd(CountdownView cv) {
//时间结束 }
});
在布局中使用也非常简单,
<cn.iwgang.countdownview.CountdownView
android:id="@+id/cv_countdownView_one"
android:layout_width="90dp"
android:layout_height="30dp"
android:layout_gravity="center_horizontal"
app:isShowDay="false"
app:isShowHour="false"
app:isShowMillisecond="true"
app:isShowMinute="true"
app:isShowSecond="true"
app:suffixGravity="center"
app:suffixTextColor="#FFFFFF"
app:suffixTextSize="14sp"
app:timeTextColor="#FFFFFF"
app:timeTextSize="14sp" />;
需要显示什么就写为true,否则false就可以了。
我觉得最关键的还是流畅不卡顿最重要。
好了,这就是我在开发倒计时的时候遇到的问题总结,希望能帮助到更多的人。谢谢,此文章是我一字一字打出来的,转载请注明。谢谢
原文来自 :http://blog.it985.com/16781.html
相关文章
- 下面我们来看一篇关于Android子控件超出父控件的范围显示出来方法,希望这篇文章能够帮助到各位朋友,有碰到此问题的朋友可以进来看看哦。 <RelativeLayout xmlns:an...2016-10-02
- 安装curl扩展支持https是非常的重要现在许多的网站都使用了https了,下面我们来看一篇关于PHP安装curl扩展支持https例子吧。 问题: 线上运行的lamp服务器,默认yu...2016-11-25
Android开发中findViewById()函数用法与简化
findViewById方法在android开发中是获取页面控件的值了,有没有发现我们一个页面控件多了会反复研究写findViewById呢,下面我们一起来看它的简化方法。 Android中Fin...2016-09-20- 如果我们的项目需要做来电及短信的功能,那么我们就得在Android模拟器开发这些功能,本来就来告诉我们如何在Android模拟器上模拟来电及来短信的功能。 在Android模拟...2016-09-20
- 夜神android模拟器如何设置代理呢?对于这个问题其实操作起来是非常的简单,下面小编来为各位详细介绍夜神android模拟器设置代理的方法,希望例子能够帮助到各位。 app...2016-09-20
- 为了增强android应用的用户体验,我们可以在一些Button按钮上自定义动态的设置一些样式,比如交互时改变字体、颜色、背景图等。 今天来看一个通过重写Button来动态实...2016-09-20
- 如果我们要在Android应用APP中加载html5页面,我们可以使用WebView,本文我们分享两个WebView加载html5页面实例应用。 实例一:WebView加载html5实现炫酷引导页面大多...2016-09-20
- 深入理解Android中View和ViewGroup从组成架构上看,似乎ViewGroup在View之上,View需要继承ViewGroup,但实际上不是这样的。View是基类,ViewGroup是它的子类。本教程我们深...2016-09-20
- 下面我们来看一篇关于Android自定义WebView网络视频播放控件开发例子,这个文章写得非常的不错下面给各位共享一下吧。 因为业务需要,以下代码均以Youtube网站在线视...2016-10-02
- java开发的Android应用,性能一直是一个大问题,,或许是Java语言本身比较消耗内存。本文我们来谈谈Android 性能优化之MemoryFile文件读写。 Android匿名共享内存对外A...2016-09-20
- TextView默认是横着显示了,今天我们一起来看看Android设置TextView竖着显示如何来实现吧,今天我们就一起来看看操作细节,具体的如下所示。 在开发Android程序的时候,...2016-10-02
android.os.BinderProxy cannot be cast to com解决办法
本文章来给大家介绍关于android.os.BinderProxy cannot be cast to com解决办法,希望此文章对各位有帮助呀。 Android在绑定服务的时候出现java.lang.ClassCastExc...2016-09-20- 这篇文章主要介绍了Android 实现钉钉自动打卡功能的步骤,帮助大家更好的理解和学习使用Android,感兴趣的朋友可以了解下...2021-03-15
- 下面我们来看一篇关于Android 开发之布局细节对比:RTL模式 ,希望这篇文章对各位同学会带来帮助,具体的细节如下介绍。 前言 讲真,好久没写博客了,2016都过了一半了,赶紧...2016-10-02
- 首先如果要在程序中使用sdcard进行存储,我们必须要在AndroidManifset.xml文件进行下面的权限设置: 在AndroidManifest.xml中加入访问SDCard的权限如下: <!--...2016-09-20
- floor会产生小数了如果我们不希望有小数我们是可以去除小数点的了,下面一聚教程小编来为各位介绍php使用floor去掉小数点的例子,希望对各位有帮助。 float floor (...2016-11-25
- 下面来给各位简单的介绍一下关于Android开发之PhoneGap打包及错误解决办法,希望碰到此类问题的同学可进入参考一下哦。 在我安装、配置好PhoneGap项目的所有依赖...2016-09-20
用Intel HAXM给Android模拟器Emulator加速
Android 模拟器 Emulator 速度真心不给力,, 现在我们来介绍使用 Intel HAXM 技术为 Android 模拟器加速,使模拟器运行度与真机比肩。 周末试玩了一下在Eclipse中使...2016-09-20- 在安卓开发时我碰到一个问题就是需要实现全屏,但又需要我们来判断出用户是使用了全屏或非全屏了,下面我分别找了两段代码,大家可参考。 先来看一个android屏幕全屏实...2016-09-20
Android开发中布局中的onClick简单完成多控件时的监听的利与弊
本文章来为各位介绍一篇关于Android开发中布局中的onClick简单完成多控件时的监听的利与弊的例子,希望这个例子能够帮助到各位朋友. 首先在一个控件加上这么一句:and...2016-09-20