Android ProgressBar具体解释以及自己定义
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd2FuZ2ppbnl1NTAx/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="" />
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd2FuZ2ppbnl1NTAx/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="" />
这样一来肯定是须要自己定义了,所以方向有两个:要么继承于系统的ProgressBar。要么继承于View类(前者就是如此实现)。那就先看一下系统的进度条吧。
对于ProgressBar的使用,有三个地方须要注意一下:
相反地。不确定的就是不清楚、不确定一个操作须要多长时间来完毕,这个时候就须要用的不确定的ProgressBar了。这个是由属性android:indeterminate来控制的,假设设置为true的话。那么ProgressBar就可能是圆形的滚动栏或者水平的滚动栏(由样式决定)。默认情况下,假设是水平进度条,那么就是确定的。
- Widget.ProgressBar.Horizontal
- Widget.ProgressBar.Small
- Widget.ProgressBar.Large
- Widget.ProgressBar.Inverse
- Widget.ProgressBar.Small.Inverse
- Widget.ProgressBar.Large.Inverse
- style="?
android:attr/progressBarStyle"
- style="?android:attr/progressBarStyleHorizontal"
- style="?android:attr/progressBarStyleInverse"
- style="?android:attr/progressBarStyleLarge"
- style="?android:attr/progressBarStyleLargeInverse"
- style="?android:attr/progressBarStyleSmall"
- style="?
android:attr/progressBarStyleSmallInverse"
- style="?
android:attr/progressBarStyleSmallTitle"
当中第一个android:animationResolution已经呗舍弃了。所以不要去研究它了。重点说一下android:progressDrawable以及android:indeterminateDrawable。那这个Drawable在ProgressBar中是怎样使用的呢,假设我们是这样在xml中设置ProgressBar的话,
<ProgressBar
android:id="@+id/progressbar"
style="@android:style/Widget.ProgressBar.Horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:secondaryProgress="50" />
尽管没有设置android:indeterminateDrawable,可是样式Widget.ProgressBar.Horizontal已经帮我们设置好了。
查看源代码例如以下:
<style name="Widget.ProgressBar.Horizontal">
<item name="android:indeterminateOnly">false</item>
<item name="android:progressDrawable">@android:drawable/progress_horizontal</item>
<item name="android:indeterminateDrawable">@android:drawable/progress_indeterminate_horizontal</item>
<item name="android:minHeight">20dip</item>
<item name="android:maxHeight">20dip</item>
<item name="android:mirrorForRtl">true</item>
</style>
<? xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2008 The Android Open Source Project Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
--> <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@android:id/background">
<shape>
<corners android:radius="5dip" />
<gradient
android:startColor="#ff9d9e9d"
android:centerColor="#ff5a5d5a"
android:centerY="0.75"
android:endColor="#ff747674"
android:angle="270"
/>
</shape>
</item> <item android:id="@android:id/secondaryProgress">
<clip>
<shape>
<corners android:radius="5dip" />
<gradient
android:startColor="#80ffd300"
android:centerColor="#80ffb600"
android:centerY="0.75"
android:endColor="#a0ffcb00"
android:angle="270"
/>
</shape>
</clip>
</item> <item android:id="@android:id/progress">
<clip>
<shape>
<corners android:radius="5dip" />
<gradient
android:startColor="#ffffd300"
android:centerColor="#ffffb600"
android:centerY="0.75"
android:endColor="#ffffcb00"
android:angle="270"
/>
</shape>
</clip>
</item> </layer-list>
二是和绘制相关的部分,如图所看到的:
所以、所以我们本次最重要的部分来了。那就是怎样自己定义一个美丽ProgressBar。
在自己定义之前。先看一下系统是怎样实现的。
Android下ProgressBar的代码量不算多,除去凝视预计也就是几百行左右。首先从构造方法看是看,
/**
* Create a new progress bar with range 0...100 and initial progress of 0.
* @param context the application environment
*/
public ProgressBar(Context context) {
this(context, null);
} public ProgressBar(Context context, AttributeSet attrs) {
this(context, attrs, com.android.internal.R.attr.progressBarStyle);
} public ProgressBar(Context context, AttributeSet attrs, int defStyle) {
this(context, attrs, defStyle, 0);
} /**
* @hide
*/
public ProgressBar(Context context, AttributeSet attrs, int defStyle, int styleRes) {
super(context, attrs, defStyle);
mUiThreadId = Thread.currentThread().getId();
initProgressBar(); TypedArray a =
context.obtainStyledAttributes(attrs, R.styleable.ProgressBar, defStyle, styleRes); mNoInvalidate = true; Drawable drawable = a.getDrawable(R.styleable.ProgressBar_progressDrawable);
if (drawable != null) {
drawable = tileify(drawable, false);
// Calling this method can set mMaxHeight, make sure the corresponding
// XML attribute for mMaxHeight is read after calling this method
setProgressDrawable(drawable);
} mDuration = a.getInt(R.styleable.ProgressBar_indeterminateDuration, mDuration); mMinWidth = a.getDimensionPixelSize(R.styleable.ProgressBar_minWidth, mMinWidth);
mMaxWidth = a.getDimensionPixelSize(R.styleable.ProgressBar_maxWidth, mMaxWidth);
mMinHeight = a.getDimensionPixelSize(R.styleable.ProgressBar_minHeight, mMinHeight);
mMaxHeight = a.getDimensionPixelSize(R.styleable.ProgressBar_maxHeight, mMaxHeight); mBehavior = a.getInt(R.styleable.ProgressBar_indeterminateBehavior, mBehavior); final int resID = a.getResourceId(
com.android.internal.R.styleable.ProgressBar_interpolator,
android.R.anim. linear_interpolator); // default to linear interpolator
if (resID > 0) {
setInterpolator(context, resID);
} setMax(a.getInt(R.styleable.ProgressBar_max, mMax)); setProgress(a.getInt(R.styleable.ProgressBar_progress, mProgress)); setSecondaryProgress(
a.getInt(R.styleable.ProgressBar_secondaryProgress, mSecondaryProgress)); drawable = a.getDrawable(R.styleable.ProgressBar_indeterminateDrawable);
if (drawable != null) {
drawable = tileifyIndeterminate(drawable);
setIndeterminateDrawable(drawable);
} mOnlyIndeterminate = a.getBoolean(
R.styleable.ProgressBar_indeterminateOnly, mOnlyIndeterminate); mNoInvalidate = false; setIndeterminate( mOnlyIndeterminate || a.getBoolean(
R.styleable.ProgressBar_indeterminate, mIndeterminate)); mMirrorForRtl = a.getBoolean(R.styleable.ProgressBar_mirrorForRtl, mMirrorForRtl); a.recycle();
}
样式文件例如以下:
R.styleable.Progre:
<declare-styleable name="ProgressBar">
<!-- Defines the maximum value the progress can take. -->
<attr name="max" format="integer" />
<!-- Defines the default progress value, between 0 and max. -->
<attr name="progress" format="integer" />
<!-- Defines the secondary progress value, between 0 and max. This progress is drawn between
the primary progress and the background. It can be ideal for media scenarios such as
showing the buffering progress while the default progress shows the play progress. -->
<attr name="secondaryProgress" format="integer" />
<!-- Allows to enable the indeterminate mode. In this mode the progress
bar plays an infinite looping animation. -->
<attr name="indeterminate" format="boolean" />
<!-- Restricts to ONLY indeterminate mode (state-keeping progress mode will not work). -->
<attr name="indeterminateOnly" format="boolean" />
<!-- Drawable used for the indeterminate mode. -->
<attr name="indeterminateDrawable" format="reference" />
<!-- Drawable used for the progress mode. -->
<attr name="progressDrawable" format="reference" />
<!-- Duration of the indeterminate animation. -->
<attr name="indeterminateDuration" format="integer" min="1" />
<!-- Defines how the indeterminate mode should behave when the progress
reaches max. -->
<attr name="indeterminateBehavior">
<!-- Progress starts over from 0. -->
<enum name="repeat" value="1" />
<!-- Progress keeps the current value and goes back to 0. -->
<enum name="cycle" value="2" />
</attr>
<attr name="minWidth" format="dimension" />
<attr name="maxWidth" />
<attr name="minHeight" format="dimension" />
<attr name="maxHeight" />
<attr name="interpolator" format="reference" />
<!-- Timeout between frames of animation in milliseconds
{@deprecated Not used by the framework.} -->
<attr name="animationResolution" format="integer" />
</declare-styleable>
private void initProgressBar() {
mMax = 100;
mProgress = 0;
mSecondaryProgress = 0;
mIndeterminate = false;
mOnlyIndeterminate = false;
mDuration = 4000;
mBehavior = AlphaAnimation.RESTART;
mMinWidth = 24;
mMaxWidth = 48;
mMinHeight = 24;
mMaxHeight = 48;
}
一是mUiThreadId,他是干嘛的呢,它获取的是当前UI线程的id,然后在更新ProgressBar进度的时候进行一个推断。假设是UI线程。那么直接进行更新,假设不是就post出去。使用Handler等进行更新。二是tileify(drawable, false)方法和tileifyIndeterminate(drawable)方法。这两个方法主要是对Drawable进行一个解析、转换的过程。在这里须要重点强调一下,在ProgressBar中,最重要的部分就是Drawable的使用了,由于不仅是它的背景包括进度等都是使用Drawable来完毕的,所以在源代码中也能够看到基本上百分之七八十的代码都是和Drawable有关的。由于这一部分篇幅较多。所以就不具体介绍了,以下重点说一下怎样绘制ProgressBar。首先看onMeasure()方法,
@Override
protected synchronized void onMeasure( int widthMeasureSpec, int heightMeasureSpec) {
Drawable d = mCurrentDrawable; int dw = 0;
int dh = 0;
if (d != null) {
dw = Math. max(mMinWidth , Math.min( mMaxWidth, d.getIntrinsicWidth()));
dh = Math. max(mMinHeight , Math.min( mMaxHeight, d.getIntrinsicHeight()));
}
updateDrawableState();
dw += mPaddingLeft + mPaddingRight;
dh += mPaddingTop + mPaddingBottom; setMeasuredDimension( resolveSizeAndState(dw, widthMeasureSpec, 0),
resolveSizeAndState(dh, heightMeasureSpec, 0));
}
这是測量View大小的方法,也就是ProgressBar的大小,由于每个ProgressBar默认都会使用Drawable。所以ProgressBar的大小即是Drawable的大小加上Padding的大小,假设没有Padding。那非常显然就是Drawable的大小。最后使用setMeasuredDimension()方法设置ProgressBar的大小。
@Override
protected synchronized void onDraw(Canvas canvas) {
super.onDraw(canvas); Drawable d = mCurrentDrawable;
if (d != null) {
// Translate canvas so a indeterminate circular progress bar with padding
// rotates properly in its animation
canvas.save();
if(isLayoutRtl() && mMirrorForRtl) {
canvas.translate(getWidth() - mPaddingRight, mPaddingTop);
canvas.scale(-1.0f, 1.0f);
} else {
canvas.translate(mPaddingLeft, mPaddingTop);
}
long time = getDrawingTime();
if ( mHasAnimation) {
mAnimation.getTransformation(time, mTransformation);
float scale = mTransformation.getAlpha();
try {
mInDrawing = true;
d.setLevel(( int) (scale * MAX_LEVEL));
} finally {
mInDrawing = false;
}
postInvalidateOnAnimation();
}
d.draw(canvas);
canvas.restore();
if ( mShouldStartAnimationDrawable && d instanceof Animatable) {
((Animatable) d).start();
mShouldStartAnimationDrawable = false ;
}
}
public boolean isLayoutRtl() {
return (getLayoutDirection() == LAYOUT_DIRECTION_RTL);
}
package android.util; /**
* A class for defining layout directions. A layout direction can be left-to-right (LTR)
* or right-to-left (RTL). It can also be inherited (from a parent) or deduced from the default
* language script of a locale.
*/
public final class LayoutDirection { // No instantiation
private LayoutDirection() {} /**
* Horizontal layout direction is from Left to Right.
*/
public static final int LTR = 0; /**
* Horizontal layout direction is from Right to Left.
*/
public static final int RTL = 1; /**
* Horizontal layout direction is inherited.
*/
public static final int INHERIT = 2; /**
* Horizontal layout direction is deduced from the default language script for the locale.
*/
public static final int LOCALE = 3;
}
最后调用Drawable对象去画出来d.draw(canvas)。
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd2FuZ2ppbnl1NTAx/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" style="text-align: -webkit-auto; " alt="" />
<?xml version= "1.0" encoding ="utf-8"? >
<resources> <declare-styleable >
<attr name= "progressIndicator" format="reference" ></attr>
<attr name= "offset" format ="dimension"></ attr>
<attr name= "textSize" format ="dimension"></ attr>
<attr name= "textColor" format="reference|color" ></attr>
<attr name= "textStyle">
<flag name= "normal" value ="0" />
<flag name= "bold" value ="1" />
<flag name= "italic" value ="2" />
</attr>
<attr name= "textAlign">
<flag name= "left" value ="0" />
<flag name= "center" value ="1" />
<flag name= "right" value ="2" />
</attr>
</declare-styleable > </resources>
/**
* @author kince
*
*/
public class IndicatorProgressBar extends ProgressBar { public IndicatorProgressBar(Context context) {
this(context, null); } public IndicatorProgressBar(Context context, AttributeSet attrs) {
this(context, attrs, 0); } public IndicatorProgressBar(Context context, AttributeSet attrs,
int defStyle) {
super(context, attrs, defStyle); } }
/**
*
*/
package com.example.indicatorprogressbar.widget; import com.example.indicatorprogressbar.R; import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Align;
import android.graphics.drawable.Drawable;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.widget.ProgressBar; /**
* @author kince
*
*/
public class IndicatorProgressBar extends ProgressBar { private TextPaint mTextPaint;
private Drawable mDrawableIndicator;
private int offset=5; public IndicatorProgressBar(Context context) {
this(context, null); } public IndicatorProgressBar(Context context, AttributeSet attrs) {
this(context, attrs, 0);
mTextPaint=new TextPaint(Paint.ANTI_ALIAS_FLAG);
mTextPaint.density=getResources().getDisplayMetrics().density; mTextPaint.setColor(Color.WHITE);
mTextPaint.setTextSize(10);
mTextPaint.setTextAlign(Align.CENTER);
mTextPaint.setFakeBoldText(true);
} public IndicatorProgressBar(Context context, AttributeSet attrs,
int defStyle) {
super(context, attrs, defStyle); TypedArray array=context.obtainStyledAttributes(attrs, R.styleable.IndicatorProgressBar, defStyle, 0);
if(array!=null){
mDrawableIndicator=array.getDrawable(R.styleable.IndicatorProgressBar_progressIndicator);
offset=array.getInt(R.styleable.IndicatorProgressBar_offset, 0);
array.recycle();
} } }
public Drawable getmDrawableIndicator() {
return mDrawableIndicator ;
}
public void setmDrawableIndicator(Drawable mDrawableIndicator) {
this.mDrawableIndicator = mDrawableIndicator;
}
public int getOffset() {
return offset ;
}
public void setOffset(int offset) {
this.offset = offset;
}
因此在onMeasure()方法中就能够这样来写:
@Override
protected synchronized void onMeasure(int widthMeasureSpec,
int heightMeasureSpec) {
// TODO Auto-generated method stub
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if(mDrawableIndicator!=null){
//获取系统进度条的宽度 这个宽度也是自己定义进度条的宽度 所以在这里直接赋值
final int width=getMeasuredWidth();
final int height=getMeasuredHeight()+getIndicatorHeight();
setMeasuredDimension(width, height);
} } /**
* @category 获取指示器的高度
* @return
*/
private int getIndicatorHeight(){
if(mDrawableIndicator==null){
return 0;
}
Rect r=mDrawableIndicator.copyBounds();
int height=r.height();
return height;
}
<style name="Widget.ProgressBar.RegularProgressBar">
<item name="android:indeterminateOnly" >false </item>
<item name="android:progressDrawable" >@drawable/progressbar </item>
<item name="android:indeterminateDrawable" >@android:drawable/progress_indeterminate_horizontal </item>
<item name= "android:minHeight">1dip</item >
<item name= "android:maxHeight">10dip</item >
</style >
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="@android:id/background"
android:drawable="@drawable/progressbar_bg" />
<item
android:id="@+id/progress"
android:drawable="@drawable/progressbar_bar" >
</item >
<item android:id="@+id/pattern">
<bitmap
android:src="@drawable/progressbar_pattern"
android:tileMode="repeat" />
</item >
</layer-list>
能够发现。是一个layer类型的drawable,所以在计算大小的时候。须要特别考虑这个情况。代码例如以下:
if (m_indicator != null) {
if (progressDrawable != null
&& progressDrawable instanceof LayerDrawable) {
LayerDrawable d = (LayerDrawable) progressDrawable;
for (int i = 0; i < d.getNumberOfLayers(); i++) {
d.getDrawable(i).getBounds(). top = getIndicatorHeight();
d.getDrawable(i).getBounds(). bottom = d.getDrawable(i)
.getBounds().height()
+ getIndicatorHeight();
}
} else if (progressDrawable != null) {
progressDrawable.getBounds(). top = m_indicator
.getIntrinsicHeight();
progressDrawable.getBounds(). bottom = progressDrawable
.getBounds().height() + getIndicatorHeight();
}
}
private void updateProgressBar () {
Drawable progressDrawable = getProgressDrawable();
if (progressDrawable != null
&& progressDrawable instanceof LayerDrawable) {
LayerDrawable d = (LayerDrawable) progressDrawable;
final float scale = getScale(getProgress());
// 获取进度条 更新它的大小
Drawable progressBar = d.findDrawableByLayerId(R.id.progress );
final int width = d.getBounds(). right - d.getBounds().left ;
if (progressBar != null) {
Rect progressBarBounds = progressBar.getBounds();
progressBarBounds. right = progressBarBounds.left
+ ( int ) (width * scale + 0.5f);
progressBar.setBounds(progressBarBounds);
}
// 获取叠加的图层
Drawable patternOverlay = d.findDrawableByLayerId(R.id.pattern );
if (patternOverlay != null) {
if (progressBar != null) {
// 使叠加图层适应进度条大小
Rect patternOverlayBounds = progressBar.copyBounds();
final int left = patternOverlayBounds.left ;
final int right = patternOverlayBounds.right ;
patternOverlayBounds. left = (left + 1 > right) ?
left
: left + 1;
patternOverlayBounds. right = (right > 0) ? right - 1
: right;
patternOverlay.setBounds(patternOverlayBounds);
} else {
// 没有叠加图层
Rect patternOverlayBounds = patternOverlay.getBounds();
patternOverlayBounds. right = patternOverlayBounds.left
+ ( int ) (width * scale + 0.5f);
patternOverlay.setBounds(patternOverlayBounds);
}
}
}
}
if (m_indicator != null) {
canvas.save();
int dx = 0;
// 获取系统进度条最右边的位置 也就是头部的位置
if (progressDrawable != null
&& progressDrawable instanceof LayerDrawable) {
LayerDrawable d = (LayerDrawable) progressDrawable;
Drawable progressBar = d.findDrawableByLayerId(R.id.progress );
dx = progressBar.getBounds(). right;
} else if (progressDrawable != null) {
dx = progressDrawable.getBounds().right ;
}
//增加offset
dx = dx - getIndicatorWidth() / 2 - m_offset + getPaddingLeft();
// 移动画笔位置
canvas.translate(dx, 0);
// 画出指示器
m_indicator .draw(canvas);
// 画出进度数字
canvas.drawText(
m_formatter != null ? m_formatter .getText(getProgress())
: Math.round(getScale(getProgress()) * 100.0f)
+ "%" , getIndicatorWidth() / 2,
getIndicatorHeight() / 2 + 1, m_textPaint );
// restore canvas to original
canvas.restore();
}
源代码下载:
Github地址:https://github.com/wangjinyu501/SaundProgressBar
Android ProgressBar具体解释以及自己定义的更多相关文章
- android动画具体解释六 XML中定义动画
动画View 属性动画系统同意动画View对象并提供非常多比view动画系统更高级的功能.view动画系统通过改变绘制方式来变换View对象,view动画是被view的容器所处理的,由于View本身没 ...
- Android ProgressBar的使用
Android 基础教程之-------Android ProgressBar的使用http://blog.csdn.net/Android_Tutor/article/details/5695170 ...
- android动画具体解释一 概述
动画和图形概述 Android 提供了大量的强大的API以应用于UI动画和绘制2D和3D图形.以下各节向你描写叙述了这些API的预览和系统能力以帮助你决定怎么才是达到你需求的最佳方法. 动画 Andr ...
- android动画具体解释二 属性动画原理
property动画是一个强大的框架,它差点儿能使你动画不论什么东西. 你能够定义一个动画来改变对象的不论什么属性,不论其是否被绘制于屏幕之上. 一个属性动画在一定时间内多次改变一个属性(对象的一个字 ...
- android动画具体解释四 创建动画
使用ValueAnimator进行动画 通过指定一些int, float或color等类型的值的集合.ValueAnimator 使你能够对这些类型的值进行动画.你需通过调用ValueAnimator ...
- 【Android实战】记录自学自己定义GifView过程,能同一时候支持gif和其它图片!【有用篇】
之前写了一篇博客.<[Android实战]记录自学自己定义GifView过程,具体解释属性那些事! [学习篇]> 关于自己定义GifView的,具体解说了学习过程及遇到的一些类的解释,然后 ...
- 使用Ant打包Android应用具体解释——Ant使用解析
上篇<使用Ant打包Android应用具体解释>描写叙述了使用Ant打包的流程,但非常多步骤并没有说明如此做的原因,本篇将从Ant方面来理解,下一篇从APK生成的流程来说明. APK包的生 ...
- Android调用系统相机、自己定义相机、处理大图片
Android调用系统相机和自己定义相机实例 本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,而且因为涉及到要把拍到的照片显示出来,该样例也会涉及到Android载入大图片时候的处 ...
- Android slidingmenu详细解释 滑动的优化
Android slidingmenu 详细解释 性能优化 转载请注明: http://blog.csdn.net/aaawqqq 简单介绍 SlidingMenu 是github 上Androi ...
随机推荐
- Sass 基础教程
0. Sass 文件后缀名 sass 有两种后缀名文件:一种后缀名为 sass,不使用大括号和分号:另一种就是我们这里使用的 scss 文件,这种和我们平时写的 css 文件格式差不多,使用大括号和分 ...
- BZOJ 3926: [Zjoi2015]诸神眷顾的幻想乡 广义后缀自动机 后缀自动机 字符串
https://www.lydsy.com/JudgeOnline/problem.php?id=3926 广义后缀自动机是一种可以处理好多字符串的一种数据结构(不像后缀自动机只有处理一到两种的时候比 ...
- Shell 学习笔记之条件语句
条件语句 if # if if condition then command fi # if else if condition then command else command fi # if e ...
- python开发_html_html处理
''' python中,html模块提供了只提供了一个方法: html.escape(s, quote = True) 该方法主要是把html文件中的特殊字符(&,<,>,&quo ...
- 一个.net下的轻量级的Serverless 文档数据库LiteDB
今天发现了一个.net下的轻量级的Serverless 文档数据库LiteDB,感觉还不错 官方网站: http://www.litedb.org/ 项目主页: https://github.com/ ...
- java基础学习总结——数组
一.数组的基本概念 数组可以看成是多个相同类型数据组合,对这些数据的统一管理. 数组变量属引用类型,数组也可以看成是对象,数组中的每个元素相当于该对象的成员变量. 数组的元素可以是任何数据类型,包括基 ...
- Android下setLatestEventInfo警告、Handler警告、SimpleDateFormat警告
正 文: 今天飘易在做Android 4.4.2下的APP开发时,使用了Notification下的setLatestEventInfo()方法时,Eclipse却提示:“ 不建议使用类型 Notif ...
- android NDK 开发环境搭建
基于 Android NDK 的学习之旅-----环境搭建 工欲善其事必先利其器 , 下面介绍下 Eclipse SDK NDK Cygwin CDT 集成开发环境的搭建. 1.Android 开发环 ...
- .NET:异常以及异常处理框架探析(转载)
概述 一般情况下,企业级应用都对应着复杂的业务逻辑,为了保证系统的健壮,必然需要面对各种系统业务异常和运行时异常. 不好的异常处理方式容易造成应用程序逻辑混乱,脆弱而难于管理.应用程序中充斥着零散的异 ...
- TextView设置最多显示指定个字符,超过部分显示...(省略号)
今天在公司遇到一个需求:TextView设置最多显示8个字符,超过部分显示...(省略号),网上找了很多资料,有人说分别设置TextView的android:signature="true& ...