内部类
调用:
A.B b=new A().new B();
A a=new A();
A.B b=a.new B();
public classA
{
public void func()
{
System.out.println("A类的实现类");
Bb=newB();
b.func();
C c=new C();
c.func(new listen() {
@Override
public void func() {
// TODO Auto-generated method stub
System.out.println("cleishix");
}
});
c.func(b);
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
}
});
}
class B implements listen
{
@Override
public void func() {
// TODO Auto-generated method stub
System.out.println("内部类的实现");
}
}
}
@Override
public booleanonTouchEvent(MotionEvent event) {
currentx=event.getX();
currenty=event.getY();
invalidate();
return true;
}
Invalidate:重绘。
Viewgroup ->linearlayout
Andriod不允许开发者启动线程访问用户的界面
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="sss"
android:background="#fe0"
android:width="200px"
android:height="60px"
android:width 不受 fill_parent影响
new Timer().schedule(new TimerTask() {
@Override
public void run() {
// TODO Auto-generated method stub
}
},0, 200);
android:layout_above="@id/view1//在莫个控件下面
android:layout_alignLeft="@id/view1"//与这个控件的排列方式
Adaterview 继承了viewGroup
Adaterview->abslistviewabsspinner adapterviewAnimator
但是都是抽象类,实际往往使用它的子类
如果<?xmlversion="1.0" encoding="utf-8"?>这句话不放在顶格紧靠左边(记住:一定要放在第一行紧靠左边,就算放在第一行空了两格或者第二行没空格都会报错),就会编译报这错误。所以以后大家出现这问题时一定要谨记,否则影响心情啊,谁晓得连这个都会出现问题呢,检查很多遍是很难检查出来这问题的。
Ui组件 viewAnimator 继承frameLayout
viewSwitcher的功能与用法
本身继承了frameLayout
可以将多个view层叠在一起,每次只显示一个组件
ViewSwitersetFactory为之设置viewFactory
11-18 05:51:14.250: D/d(1193): 【总统】任务<ACTION_DOWN>: 需要分派
11-18 05:51:14.250: D/d(1193): 【省长】任务<ACTION_DOWN>: 需要分派
11-18 05:51:14.250: D/d(1193): 【省长】任务<ACTION_DOWN>: 拦截吗?false
11-18 05:51:14.287: D/d(1193): 【市长】任务<ACTION_DOWN>: 需要分派
11-18 05:51:14.287: D/d(1193): 【市长】任务<ACTION_DOWN>: 拦截吗?true
11-18 05:51:14.290: D/d(1193): 【市长】任务<ACTION_DOWN>: 农民真没用,下次再也不找你了,我自己来尝试一下。能解决?false
11-18 05:51:14.290: D/d(1193): 【省长】任务<ACTION_DOWN>: 市长是个废物,下次再也不找你了,我自己来尝试一下。能解决?false
11-18 05:51:14.290: D/d(1193): 【总统】任务<ACTION_DOWN>: 下面都解决不了,下次再也不能靠你们了,哼…只能自己尝试一下啦。能解决?false
11-18 05:51:14.321: D/d(1193): 【总统】任务<ACTION_UP>: 需要分派
11-18 05:51:14.321: D/d(1193): 【总统】任务<ACTION_UP>: 下面都解决不了,下次再也不能靠你们了,哼…只能自己尝试一下啦。能解决?false
11-18 06:05:42.910: D/d(1241): 【总统】任务<ACTION_DOWN>: 需要分派
11-18 06:05:42.910: D/d(1241): 【省长】任务<ACTION_DOWN>: 需要分派
11-18 06:05:42.910: D/d(1241): 【省长】任务<ACTION_DOWN>: 拦截吗?false
11-18 06:05:42.910: D/d(1241): 【市长】任务<ACTION_DOWN>: 需要分派
11-18 06:05:42.910: D/d(1241): 【市长】任务<ACTION_DOWN>: 拦截吗?true
11-18 06:05:42.920: D/d(1241): 【市长】任务<ACTION_DOWN>: 农民真没用,下次再也不找你了,我自己来尝试一下。能解决?true
11-18 06:05:42.985: D/d(1241): 【总统】任务<ACTION_UP>: 需要分派
11-18 06:05:42.985: D/d(1241): 【省长】任务<ACTION_UP>: 需要分派
11-18 06:05:42.985: D/d(1241): 【省长】任务<ACTION_UP>: 拦截吗?false
11-18 06:05:42.985: D/d(1241): 【市长】任务<ACTION_UP>: 需要分派
11-18 06:05:42.985: D/d(1241): 【市长】任务<ACTION_UP>: 农民真没用,下次再也不找你了,我自己来尝试一下。能解决?true
newInitTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
MMS 是一种串流媒体传输协议 (Microsoft media serverprotocol)
引入vitamo框架进行播放。
引入vitamo工程
检查vitamo引擎的安装
2.bitmap的管理,bitmap稍微管理不当,就有可能引发oom,andriod2.3 api 10存在差异,
Bitmap对象和数据是分开存的,对象存在 dalvikheap,bitmap对象的像素存在直接内存中,我们可以调用recycle()来释放对象,如果你调用了bitmap对象reclycle之后,在将bitmap绘制出来,就会出现canvas:tryingtouse 。在api11 bitmap对象和像素一起存在dalvik heap中
我们不用手动调用reclycle来释放对象,内存释放都交给了垃圾回收。
内存泄露,我们去引用会发生oom,如果对象还活着,我们就要减少对内存的消耗,应该根据view的大小对bitmap进行相应的裁剪。
//获取移动最小的距离,只有大于这个距离才可以认为是滑动
原来他里面调用了scrollTo()方法,那就好办了,他就是相对于View上一个位置根据(x, y)来进行滚动,可能大家脑海中对这两个方法还有点模糊,没关系,还是举个通俗的例子帮大家理解下,假如一个View,调用两次scrollTo(-10,0),第一次向右滚动10,第二次就不滚动了,因为mScrollX和x相等了,当我们调用两次scrollBy(-10,0),第一次向右滚动10,第二次再向右滚动10,他是相对View的上一个位置来滚动的。
对于scrollTo()和scrollBy()方法还有一点需要注意,这点也很重要,假如你给一个LinearLayout调用scrollTo()方法,并不是LinearLayout滚动,而是LinearLayout里面的内容进行滚动,比如你想对一个按钮进行滚动,直接用Button调用scrollTo()一定达不到你的需求,大家可以试一试,如果真要对某个按钮进行scrollTo()滚动的话,我们可以在Button外面包裹一层Layout,然后对Layout调用scrollTo()方法
Scoller->startscroll
之后就会引发view->dispatchdrawView-(drawchild()方法)->drawchild(child.computeScroll);
Ondraw dispatchdraw的区别
绘制view 的本身内容,通过view.onDraw(canvas)实现
绘制自己的孩子通过dispathchDraw(canvas)实现
Viewgroup容器,当没有背景时直接调用dispathcDraw,而绕过draw方法
Viewgroup 绘制过程
OnMeasure :
childcount 个数
获取viewgroup的实际长度和宽度
//设置本ViewGroup的宽高
setMeasuredDimension(specSize_Widht ,specSize_Heigth) ;
for(inti=0 ;i<childCount ; i++){
View child = getChildAt(i); //获得每个对象的引用
child.measure(50, 50) ; //简单的设置每个子View对象的宽高为 50px , 50px
//或者可以调用ViewGroup父类方法measureChild()或者measureChildWithMargins()方法
this.measureChild(child, widthMeasureSpec, heightMeasureSpec) ;
}
Onlayout
int childCount = getChildCount() ;
int startLeft = 0 ;//设置每个子View的起始横坐标
int startTop = 10 ; //每个子View距离父视图的位置,简单设置为10px吧。可以理解为 android:margin=10px ;
Log.i(TAG, "**** onLayout start ****") ;
for(int i=0 ;i<childCount ; i++){
View child = getChildAt(i); //获得每个对象的引用
child.layout(startLeft,startTop, startLeft+child.getMeasuredWidth(),startTop+child.getMeasuredHeight()) ;
startLeft=startLeft+child.getMeasuredWidth() + 10; //校准startLeft值,View之间的间距设为10px ;
Log.i(TAG, "**** onLayout startLeft ****" +startLeft) ;
}
On dispathcvew
Drawchild
Myview is onDraw
在线程里面要用getResover,必须这样用 mainactivity.this.getresover();
contentResolver详解
publicfinal Cursor query (Uri uri, String[] projection,String selection,String[] selectionArgs, StringsortOrder)
第一个参数,uri,rui是什么呢?好吧,上面我们提到了Android提供内容的叫Provider,那么在Android中怎么区分各个Provider?有提供联系人的,有提供图片的等等。所以就需要有一个唯一的标识来标识这个Provider,Uri就是这个标识,android.provider.ContactsContract.Contacts.CONTENT_URI就是提供联系人的内容提供者,可惜这个内容提供者提供的数据很少。
第二个参数,projection,真不知道为什么要用这个单词,这个参数告诉Provider要返回的内容(列Column),比如Contacts Provider提供了联系人的ID和联系人的NAME等内容,如果我们只需要NAME,那么我们就应该使用:
[java] view plaincopy
1. Cursor cursor = contentResolver.query(android.provider.ContactsContract.Contacts.CONTENT_URI,
2. new String[]{android.provider.ContactsContract.Contacts.DISPLAY_NAME}, null, null, null);
当然,下面打印的你就只能显示NAME了,因为你返回的结果不包含ID。用null表示返回Provider的所有内容(列Column)。
第三个参数,selection,设置条件,相当于SQL语句中的where。null表示不进行筛选。如果我们只想返回名称为张三的数据,第三个参数应该设置为:
[java] view plaincopy
1. Cursor cursor = contentResolver.query(android.provider.ContactsContract.Contacts.CONTENT_URI,
2. new String[]{android.provider.ContactsContract.Contacts.DISPLAY_NAME},
3. android.provider.ContactsContract.Contacts.DISPLAY_NAME + "='张三'", null, null);
结果:
[java] view plaincopy
1. 11-05 15:30:32.188: I/System.out(10271): 张三
第四个参数,selectionArgs,这个参数是要配合第三个参数使用的,如果你在第三个参数里面有?,那么你在selectionArgs写的数据就会替换掉?,
[java] view plaincopy
1. Cursor cursor = contentResolver.query(android.provider.ContactsContract.Contacts.CONTENT_URI,
2. new String[]{android.provider.ContactsContract.Contacts.DISPLAY_NAME},
3. android.provider.ContactsContract.Contacts.DISPLAY_NAME + "=?",
4. new String[]{"张三"}, null);
效果和上面一句的效果一样。
第五个参数,sortOrder,按照什么进行排序,相当于SQL语句中的Orderby。如果想要结果按照ID的降序排列:
[java] view plaincopy
1. Cursor cursor = contentResolver.query(android.provider.ContactsContract.Contacts.CONTENT_URI,
2. null, null,null, android.provider.ContactsContract.Contacts._ID + " DESC");
结果:
[java] view plaincopy
1. 11-05 16:00:32.808: I/System.out(12523): 31
2. 11-05 16:00:32.808: I/System.out(12523): 李四
3. 11-05 16:00:32.817: I/System.out(12523): 13
4. 11-05 16:00:32.817: I/System.out(12523): 张三
升序,其实默认排序是升序,+" ASC"写不写效果都一样:
public boolean onTouch(View view, MotionEvent event)
1. x = (int) event.getX();
2. y = (int) event.getY();
3. rawx = (int) event.getRawX();
4. rawy = (int) event.getRawY();
至于什么invalidate,invalidate是做什么用的。
当invalidate方法被调用的时候,就是在告诉系统,当前的view发生改变,应该尽可能快的来进行重绘。
这个方法仅能在UI线程中被调用。如果想要在工作线程中进行刷新界面,那么其他的方法将会被调用,这个方法就是postInvalidate方法。
但是需要注意的是,刷新界面并不能保证马上刷新。只是尽可能快的进行刷新。尤其是在postInvalidate方法中,这种情况会出现
private VelocityTracker mVelocityTracker;//生命变量
//在onTouchEvent(MotionEvent ev)中
if (mVelocityTracker == null) {
mVelocityTracker = VelocityTracker.obtain();//获得VelocityTracker类实例
}
mVelocityTracker.addMovement(ev);//将事件加入到VelocityTracker类实例中
//判断当ev事件是MotionEvent.ACTION_UP时:计算速率
final VelocityTracker velocityTracker = mVelocityTracker;
// 1000 provides pixels per second
velocityTracker.computeCurrentVelocity(1, (float)0.01); //设置maxVelocity值为0.1时,速率大于0.01时,显示的速率都是0.01,速率小于0.01时,显示正常
1. 参数:units 你想要指定的得到的速度单位,如果值为1,代表1毫秒运动了多少像素。如果值为1000,代表
2. * 1秒内运动了多少像素
Log.i("test","velocityTraker"+velocityTracker.getXVelocity());
velocityTracker.computeCurrentVelocity(1000);//设置units的值为1000,意思为一秒时间内运动了多少个像素
Log.i("test","velocityTraker"+velocityTracker.getXVelocity());
大体的使用是这样的:
当你需要跟踪触摸屏事件的速度的时候,使用obtain()方法来获得VelocityTracker类的一个实例对象
在onTouchEvent回调函数中,使用addMovement(MotionEvent)函数将当前的移动事件传递给VelocityTracker对象
使用computeCurrentVelocity (int units)函数来计算当前的速度,使用getXVelocity ()、getYVelocity ()函数来获得当前的速度
1. 09-06 09:57:27.287: E/MyLinearLayout(959):dispatchTouchEvent ACTION_DOWN
2. 09-06 09:57:27.287: E/MyLinearLayout(959):onInterceptTouchEvent ACTION_DOWN
3. 09-06 09:57:27.287: E/MyButton(959):dispatchTouchEvent ACTION_DOWN
4. 09-06 09:57:27.297: E/MyButton(959):onTouchEvent ACTION_DOWN
5. 09-06 09:57:27.297: E/MyButton(959):onTouchEvent ACTION_MOVE
6. 09-06 09:57:27.327: E/MyLinearLayout(959):dispatchTouchEvent ACTION_MOVE
7. 09-06 09:57:27.327: E/MyLinearLayout(959):onInterceptTouchEvent ACTION_MOVE
8. 09-06 09:57:27.337: E/MyButton(959):dispatchTouchEvent ACTION_MOVE
9. 09-06 09:57:27.337: E/MyButton(959):onTouchEvent ACTION_MOVE
10. 09-06 09:57:27.457: E/MyLinearLayout(959):dispatchTouchEvent ACTION_UP
11. 09-06 09:57:27.457: E/MyLinearLayout(959):onInterceptTouchEvent ACTION_UP
12. 09-06 09:57:27.457: E/MyButton(959):dispatchTouchEvent ACTION_UP
13. 09-06 09:57:27.457: E/MyButton(959):onTouchEvent ACTION_UP
1、如果ViewGroup找到了能够处理该事件的View,则直接交给子View处理,自己的onTouchEvent不会被触发;
2、可以通过复写onInterceptTouchEvent(ev)方法,拦截子View的事件(即return true),把事件交给自己处理,则会执行自己对应的onTouchEvent方法
3、子View可以通过调用getParent().requestDisallowInterceptTouchEvent(true); 阻止ViewGroup对其MOVE或者UP事件进行拦截;
1. 08-31 06:09:39.030: E/MyButton(879):dispatchTouchEvent ACTION_DOWN
2. 08-31 06:09:39.030: E/MyButton(879):onTouch ACTION_DOWN
3. 08-31 06:09:39.049: E/MyButton(879):onTouchEvent ACTION_DOWN
4. 08-31 06:09:39.138: E/MyButton(879):dispatchTouchEvent ACTION_MOVE
5. 08-31 06:09:39.138: E/MyButton(879):onTouch ACTION_MOVE
6. 08-31 06:09:39.147: E/MyButton(879):onTouchEvent ACTION_MOVE
7. 08-31 06:09:39.232: E/MyButton(879):dispatchTouchEvent ACTION_UP
8. 08-31 06:09:39.248: E/MyButton(879):onTouch ACTION_UP
9. 08-31 06:09:39.248: E/MyButton(879):onTouchEvent ACTION_UP
整个View的事件转发流程是:
View.dispatchEvent->View.setOnTouchListener->View.onTouchEvent
在dispatchTouchEvent中会进行OnTouchListener的判断,如果OnTouchListener不为null且返回true,则表示事件被消费,onTouchEvent不会被执行;否则执行onTouchEvent。
1. publicbooleandispatchTouchEvent(MotionEvent event) {
2. if(!onFilterTouchEventForSecurity(event)) {
3. returnfalse;
4. }
5.
6. if (mOnTouchListener != null &&(mViewFlags & ENABLED_MASK) == ENABLED &&
7. mOnTouchListener.onTouch(this, event)) {
8. returntrue;
9. }
10. return onTouchEvent(event);
11. }
11-28 04:54:29.913:I/System.out(800): Activity dispatchTouch Action_down
11-28 04:54:29.913:I/System.out(800): linearout dispatchTouch Action_down
11-28 04:54:29.913:I/System.out(800): linearout onInterceptTouchEvent Action_down
11-28 04:54:29.913:I/System.out(800): button dispatchTouch Action Down
11-28 04:54:29.925:I/System.out(800): button TouchEvent Action Down
11-28 04:54:29.925:I/System.out(800): linearout onTouch Action_down
11-28 04:54:29.925:I/System.out(800): Activity onTouch Action_down
11-28 04:54:30.013:I/System.out(800): Activity dispatchTouch Action_up
11-28 04:54:30.013:I/System.out(800): Activity onTouch Action_up
11-28 04:56:34.968:I/System.out(847): Activity dispatchTouch Action_down
11-28 04:56:34.973:I/System.out(847): linearout dispatchTouch Action_down
11-28 04:56:34.983:I/System.out(847): linearout onInterceptTouchEvent Action_down
11-28 04:56:34.983:I/System.out(847): button dispatchTouch Action Down
11-28 04:56:34.983:I/System.out(847): button TouchEvent Action Down
11-28 04:56:34.983:I/System.out(847): linearout onTouch Action_down
11-28 04:56:34.983:I/System.out(847): Activity onTouch Action_down
11-28 04:56:35.067:I/System.out(847): Activity dispatchTouch Action_up
11-28 04:56:35.073:I/System.out(847): Activity onTouch Action_up
Viewholder作用,通过convertview.setttag与converviewj进行绑定,然后converview复用,直接从viewholder,(gertag)拿到从verview中的布局中控件省去了findview by id的时间
Fragment 时activity一定要要继承fragmentactivity,否则会异常
自定义view时,构造方法要写, custouview(xx ,atrribude xx)
ViewGroup.MarginLayoutParams 主要定义和四周边缘的空白。
Widthmeasurespec 和heightmeasurespec不是一般的尺寸数值,而是将模式和尺寸组合在一起的数值。我们要通过 intmode=measurespec。Getmode()得到模式,用intmeasurespec.getsize(widthMeasuere) 得到size;
==
Parent root
result=root;
Attr=xml.asAttributeset(paser);
View Temp=createvieweithtag(attr);
If(root!=null)
{
Paras=root.genertelayoutparams(attrs);
}
Temp.setlayoutparams(params);
If(root!=null&& attachroot)
{
Root.addview(temp);
}
Else
{
Result=temp;
}
Return result;
Inflate(resid,null) 之创建了temp 返回temp
Inflate(resid ,parent,false) 创建temp,然后执行temp ,然后执行
Temp.setlayoutparams(params).返回temp
Inflate(resid,parent,true) 创建temp,然后执行root.addview(temp.params)是返回root
Inflate(reid,null)) 不能正确处理宽和高因为,layout_width,layout_heigt,是相对于父级设置的,必须与layoutparams一致,而此temp的getlayoutpara 为null。
Infate(resid,parent,fase) 可以正确处理,因为temp.setlayoutparams(params),这个params正是
root.generateLayoutParams(attr);
inflate(reid,parent.true) 不能正确处理,而且已经把resid这个view 加入到parent,并且返回parent,,和以上返回的有绝对的区别,所以myadapter 里面会报错。
Final attributeSetattrs=xml.asAttributeSet(parser)
当root为null的时候,是不执行parsms=root.generateLayoutparams(attr)
这句的意思就是把layoutparams转换成layoutparams,换句话说就是加载我们de
布局属性。以供布局类(FrameLayout等)在onLayout的时候控制view的大小,位置
Public LayoutParamsgenerateLayoutParams(AttributeSet attr)
{
Return newFramelayout.LayoutParams(getContext,attrs);
}
FramLayout属性有
(1) layout_width
(2)layout_height
(3)layout_marginLeft
(4)layout_marginTop
(5)layout_marginRight
(6)layout_marginBottom
(7)layout_gravity
@Override
public LayoutParamsgenerateLayoutParams(AttributeSet attrs) {
// TODO Auto-generated method stub
return newLinearLayout.LayoutParams(getContext(), attrs);
}
ViewGroup.LayoutParams params =null;
params=Root.generateLayoutParms(attr);
temp.setlayoutparas(paras);
Fragment 使用了replace方法,repace是remove和add的合体,如果不添加事务的到回退站,前一个fragment实例会被销毁,我们调用了tx.addtobackstatck(null),将当前的食物加到回退站,
所以fragmentone实例不会被销毁,但是试图层次依然会被销毁,即会调用destroty.oncreateView.
Fragment replace:
AddTobackstack(null)
12-03 08:48:15.509:I/System.out(916): FragmentoneCreateView
12-03 08:48:33.429:I/System.out(916): Fragmenttwo oncreateView
12-03 08:50:30.022:I/System.out(916): FragmentTwo destroy
12-03 08:50:30.022:I/System.out(916): FragmentoneCreateView //重点??????
Fragmentone destroy
单击回退键:
FragmentTwo destrory
Fragmentone createview
没有AddTobackStack(null)
12-03 08:45:51.434:I/System.out(869): FragmentoneCreateView
12-03 08:45:57.459:I/System.out(869): Fragmentone destroy
12-03 08:45:57.459: I/System.out(869):Fragmenttwo oncreateView
Add 时候
12-03 08:52:54.430:I/System.out(1013): FragmentoneCreateView
12-03 08:53:02.569:I/System.out(1013): Fragmenttwo oncreateView
12-03 08:53:10.520:I/System.out(1013): FragmentTwo destroy
12-03 08:53:14.810: I/System.out(1013):Fragmentone destroy
Android 一定要写入权限。
Bitmap bitmap2=Bitmap.createBitmap(bitmap.getWidth(),bitmap.getHeight(), Config.ARGB_8888);
Canvas canvas=new Canvas(bitmap2);
Paint paint=new Paint();
final int color = 0xff424242;
paint.setColor(color);
canvas.drawBitmap(bitmap2, rect,rect, paint);
1. Bitmap bitmap = Bitmap.createBitmap(width,height,
2. drawable.getOpacity() != PixelFormat.OPAQUE? Bitmap.Config.ARGB_8888
3. : Bitmap.Config.RGB_565);
4. Canvas canvas = new Canvas(bitmap);
5. drawable.setBounds(0,0,width,height);
6. drawable.draw(canvas); //将drawable对象花在屏幕上
7. return bitmap;
Paint 就是画笔
Bitmap 就是画布
Canvas 就是画家
myTextView=(TextView)view.findViewById(R.id.imagename);
myImageView=(ImageView)view.findViewById(R.id.imageview);
千万不要忘记view.findviewbyid(); // view.