您的位置:

首页 >

365体育官网备用网址 >

Android 控件(button)对齐方法实现详解 >

Android 控件(button)对齐方法实现详解

2016-06-24 12:11:42

分类:365体育官网备用网址

1,android:orientation 布局方向。horizontal是让所有的子元素按水平方向从左到右排列, vertical是让所有的子元素按竖直方向从上到下排列。 2,android:gravity 与 android:layout_gravity的区别android:gravity是指定本元素的子元素相对它的对齐方式。 android:layout_gravity是指定本元素相对它的父元素的对齐方式。 例如: 下面这里的linearlayout的android:gravity设为right,有两个子元素Button01和Button02。 java代码: 复制代码 代码如下: <?xml version=”1.0″ encoding=”utf-8″?> <LinearLayout xmlns:android=”http://schemas.android.com/apk/res/android” android:orientation=”vertical” android:layout_width=”fill_parent” android:layout_height=”fill_parent” android:gravity=”right” > <Button android:text=”button01″ android:id=”@+id/Button01″ android:layout_width=”wrap_content” android:layout_height=”wrap_content”></Button> <Button android:text=”button02″ android:id=”@+id/Button02″ android:layout_width=”wrap_content” android:layout_height=”wrap_content”></Button> </LinearLayout> 这个main.xml里的LinearLayout也是有两个子元素Button01和Button02。Button01的android:layout_gravity设为”left”,Button02的 android:layout_gravity设为”right” java代码: 复制代码 代码如下: <?xml version=”1.0″ encoding=”utf-8″?> <LinearLayout xmlns:android=”http://schemas.android.com/apk/res/android” android:orientation=”vertical” android:layout_width=”fill_parent” android:layout_height=”fill_parent” > <Button android:layout_gravity=”left” android:text=”button01″ android:id=”@+id/Button01″ android:layout_width=”wrap_content” a ndroid:layout_height=”wrap_content”></Button> <Button android:layout_gravity=”right” android:text=”button02″ android:id=”@+id/Button02″ android:layout_width=”wrap_content” android:layout_height=”wrap_content”> </Button> </LinearLayout> FameLayout布局 FrameLayout是最简单的一个布局对象。它被定制为你屏幕上的一个空白备用区域,之后你可以在其中填充一个单一对象—比如,一张你要发布的图片。所有的子元素将会固定在屏幕的左上角;你不能为FrameLayout中的一个子元素指定一个位置。后一个子元素将会直接在前一个子元素之上进行覆盖填充,把它们部份或全部挡住(除非后 一个子元素是透明的)。xml属性 1,用xml文件来定义界面,然后Activity的setContentView方法根据xml文件里的定义来创建真正的控件对象。好比说xml文件是设计图纸,setContentView是生产机器,它依照图纸生产出各种各样的杯具和洗具。 2,FrameLayout的xml属性来自三个地方:继承下来的,嵌套类定义的,自身类定义的。 3,具的属性可查阅官方文档。下面是刚才遇到的几个属性。 java代码: 复制代码 代码如下: android:id //这个xml属性是继承自android.view类的xml属性。它为framelayout提供一个唯一识别符号,之后,程序要用到它时可以用View.findViewById() 或Activity.findViewById()来找到它。 android:layout_width: 布局宽 android:layout_height: 布局高 //它们的取值是fill_parent或wrap_content。 fill_parent :在x轴或则y轴上充满父容器的空间。 wrap_content :framelayout里的元素有多少宽高就多少宽高, //这两个属性都是定义在android.widget.FrameLayout的嵌套类android.widget.FrameLayout.LayoutParams里。 android:background:背景 android:foreground :

本文实例讲述了Android编程之View简单学习示例。分享给大家供大家参考,具体如下:View,是Android的一个超类,这个类几乎包含了所有的屏幕类型。每一个View都有一个用于绘图的画布,这个画布可以进行任意扩展。在游戏开发中叶可以自定义视图(View),这个画布的功能更能满足我们在游戏开发中的需要。在Android中,任何一个View类都只需重写onDraw 方法来实现界面显示,自定义的视图可以是复杂的3D实现,也可以是非常简单的文本形式等。游戏的核心是不断地绘图和刷新界面,Android中提供了 invalidate 方法来实现界面刷新。注意,invalidate 不能直接在线程中调用, 就是不可以在子线程中调用,因此它违背了 Android的单线程模型:Android UI操作并不是线程安全的,并且这些操作必须在UI 线程中执行,因此Android中最常用的方法就是利用Handler来实现UI线程的更新。 其实用 AsyncTask 也可以。具体示例:Activity:public class Activity01 extends Activity { private static final String TAG = "mThread"; private static final int REFRESH = 0x000001; private GameView mGameView = null; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); this.mGameView = new GameView(this); mGameView.x = 320.0f; mGameView.y = 120.0f; setContentView(mGameView); new Thread(new GameThread()).start(); } Handler myHandler = new Handler() { @Override public void handleMessage(Message msg) { switch (msg.what) { case Activity01.REFRESH: mGameView.invalidate(); // repaint View break; } super.handleMessage(msg); } }; class GameThread implements Runnable { @Override public void run() { while (!Thread.currentThread().isInterrupted()) { Message message = new Message(); message.what = Activity01.REFRESH; Activity01.this.myHandler.sendMessage(message); try { Thread.sleep(1000); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } } } @Override public boolean onTouchEvent(MotionEvent event) { if(event.getAction() == MotionEvent.ACTION_DOWN){ mGameView.x = event.getX(); mGameView.y = event.getY(); } return true; } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if(keyCode == KeyEvent.KEYCODE_BACK){ this.finish(); } return true; } }gameview:public class GameView extends View { int count = 0; float x = 0, y = 0; public GameView(Context context) { super(context); } public void onDraw(Canvas canvas) { if (count < 100) { count++; } else { count = 0; } Paint mPaint = new Paint(); switch (count % 4) { case 0: mPaint.setColor(Color.BLUE); break; case 1: mPaint.setColor(Color.GREEN); break; case 2: mPaint.setColor(Color.RED); break; case 3: mPaint.setColor(Color.YELLOW); break; default: mPaint.setColor(Color.WHITE); break; } canvas.drawRect(x - 40, y - 20, x + 40, y + 20, mPaint); } }运行效果:完整实例代码代码点击此处本站下载。希望本文所述对大家Android程序设计有所帮助。

第一种方法:获取手机的IMSI码,并判断是中国移动\中国联通\中国电信TelephonyManager telManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);/** 获取SIM卡的IMSI码* SIM卡唯一标识:IMSI 国际移动用户识别码(IMSI:International Mobile Subscriber Identification Number)是区别移动用户的标志,* 储存在SIM卡中,可用于区别移动用户的有效信息。IMSI由MCC、MNC、MSIN组成,其中MCC为移动国家号码,由3位数字组成,* 唯一地识别移动客户所属的国家,我国为460;MNC为网络id,由2位数字组成,* 用于识别移动客户所归属的移动网络,中国移动为00,中国联通为01,中国电信为03;MSIN为移动客户识别码,采用等长11位数字构成。* 唯一地识别国内GSM移动通信网中移动客户。所以要区分是移动还是联通,只需取得SIM卡中的MNC字段即可*/String imsi = telManager.getSubscriberId();if(imsi!=null){if(imsi.startsWith("46000") || imsi.startsWith("46002")){//因为移动网络编号46000下的IMSI已经用完,所以虚拟了一个46002编号,134/159号段使用了此编号//中国移动}else if(imsi.startsWith("46001")){//中国联通}else if(imsi.startsWith("46003")){//中国电信}} 第二种方法TelephonyManager telManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);String operator = telManager.getSimOperator();if(operator!=null){if(operator.equals("46000") || operator.equals("46002")){//中国移动}else if(operator.equals("46001")){//中国联通}else if(operator.equals("46003")){//中国电信}}以上所述是小编给大家介绍的Android 判断SIM卡是中国移动\中国联通\中国电信(移动运营商),希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!

MediaRecorderAndroid的MediaRecorder包含了Audio和video的记录功能,在Android的界面上,Music和Video两个应用程序都是调用MediaRecorder实现的。MediaRecorder在底层是基于OpenCore(PacketVideo)的库实现的,为了构建一个MediaRecorder程序,上层还包含了进程间通讯等内容,这种进程间通讯的基础是Android基本库中的Binder机制。以开源的Android为例MediaRecorder的代码主要在以下的目录中:JAVA程序的路径:packages/apps/Camera/src/com/android/camera/VideoCamera.javaJAVA Framework的路径:frameworks/base/media/java/android/media/MediaRecorder.javaJAVA本地调用部分(JNI):frameworks/base/media/jni/android_media_MediaRecorder.cpp这部分内容编译成为目标是libmedia_jni.so。主要的头文件在以下的目录中:frameworks/base/include/media/多媒体底层库在以下的目录中:frameworks/base/media/libmedia/ 这部分的内容被编译成库libmedia.so。多媒体服务部分:frameworks/base/media/libmediaplayerservice/MediaRecorder和MeidaPlayer使用相同的服务。基于OpenCore部分 external/opencore/android/author这部分内容被编译成库libopencoreauthor.so。基本的录音功能实现:好了,了解了大概的路径,具体的调用MediaRecorder的内容便可以深入各文件中去研究,接下来我们便直接来看例子,这个录音器的代码实现的说明都写在了注释中,非常简单:  import java.io.IOException; import android.app.Activity; import android.media.MediaRecorder; import android.os.Bundle; /** * @description 对通过android系统手机进行录音的一点说明测试 * @author chenzheng_java * @since 2011/03/23 */ public class MediaRecordActivity extends Activity { MediaRecorder mediaRecorder ; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mediaRecorder = new MediaRecorder(); record(); } /** * 开始录制 */ private void record(){ /** * mediaRecorder.setAudioSource设置声音来源。 * MediaRecorder.AudioSource这个内部类详细的介绍了声音来源。 * 该类中有许多音频来源,不过最主要使用的还是手机上的麦克风,MediaRecorder.AudioSource.MIC */ mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); /** * mediaRecorder.setOutputFormat代表输出文件的格式。该语句必须在setAudioSource之后,在prepare之前。 * OutputFormat内部类,定义了音频输出的格式,主要包含MPEG_4、THREE_GPP、RAW_AMR……等。 */ mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); /** * mediaRecorder.setAddioEncoder()方法可以设置音频的编码 * AudioEncoder内部类详细定义了两种编码:AudioEncoder.DEFAULT、AudioEncoder.AMR_NB */ mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT); /** * 设置录音之后,保存音频文件的位置 */ mediaRecorder.setOutputFile("file:///sdcard/myvido/a.3pg"); /** * 调用start开始录音之前,一定要调用prepare方法。 */ try { mediaRecorder.prepare(); mediaRecorder.start(); } catch (IllegalStateException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } /*** * 此外,还有和MediaRecorder有关的几个参数与方法,我们一起来看一下: * sampleRateInHz :音频的采样频率,每秒钟能够采样的次数,采样率越高,音质越高。 * 给出的实例是44100、22050、11025但不限于这几个参数。例如要采集低质量的音频就可以使用4000、8000等低采样率 * * channelConfig :声道设置:android支持双声道立体声和单声道。MONO单声道,STEREO立体声 * * recorder.stop();停止录音 * recorder.reset(); 重置录音 ,会重置到setAudioSource这一步 * recorder.release(); 解除对录音资源的占用 */ }  这里,一定要注意一点,那就是如果我们想要录音的话,那么首先得添加录音权限到AndroidManiferst.xml中:<uses-permission android:

RecyclerView的优势: 它自带ViewHolder来实现View的复用机制,再也不用ListView那样在getView()里自己写了 使用LayoutManager可以实现ListView,GridView以及流式布局的列表效果 通过setItemAnimator(ItemAnimator animator)可以实现增删动画(懒的话,可以使用默认的ItemAnimator对象,效果也不错) 控制item的间隔,可以使用addItemDecoration(ItemDecoration decor),不过里边的ItemDecoration是一个抽象类,需要自己去实现...用法介绍:导入RecyclerView的v7库:RecyclerView是一个android.support.v7库里的控件,因此在使用的时候我们需要在gradle配置文件里加上compile 'com.android.support:recyclerview-v7:22.2.1'来引入google官方的这个库xml布局中,使用常规的控件引入方式,来引入RecyclerView,如下: <android.support.v7.widget.RecyclerView android:id="@+id/recyclerview_content" style="?recyclerview_style" android:scrollbars="vertical" android:fadeScrollbars="true" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginBottom="-55dp" />代码中的写法基本和ListView相差无几,但还是要重点说一下:在实例化RecyclerView之后,我们需要使用setLayoutManager()给它设置布局管理器,其中的实参即就是LayoutManager,这里总共有两种LayoutManager:1.StaggeredGridLayoutManager,是我们之前提到的流式布局:它有一个构造方法StaggeredGridLayoutManager(int spanCount, int orientation),第一个是网格的列数,第二个参数是数据呈现的方向(如果是竖直,那么第一个参数的意义就是列数,反之为行数。而且第二个参数在StaggeredGridLayoutManager里也有同样名称的常量,请同学们自行采纳[这里还是建议大家使用库里自带的常量,因为他们一般都是整型值,这样可以避免各个类里所判别的常量值不一样而导致的其他问题]);2.GridLayoutManager,网格布局(流式布局应该是它的一个特殊情况):GridLayoutManager(Context context, int spanCount)或GridLayoutManager(Context context, int spanCount, int orientation, boolean reverseLayout)需要说明的是,最后一个参数表示的是是否逆向布局(意思是将数据反向显示,原先从左向右,从上至下。设为true之后全部逆转)。小提示:在这两个LayoutManager中,默认的orientation为vertical,reverseLayout为false。对应的参数在GridLayoutManager中都有对应的方法来进行补充设置。而在StaggeredGridLayoutManager中所有的方法都针对reverseLayout做了判断,然而它并没有给出这个参数设定值的api。线性布局, LinearLayoutManagerLinearLayoutManager(Context context)构建一个默认布局方向为VERTICAL的RecyclerView,这种样式也是ListView默认的。LinearLayoutManager(Context context, int orientation, boolean reverseLayout)。发现没有,线性布局和网格布局几乎是一样的。只是少了一个spanCount参数。和ListView一样,为RecyclerView设置Adapter class HomeAdapter extends RecyclerView.Adapter<HomeAdapter.MyViewHolder> { @Override public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { MyViewHolder holder = new MyViewHolder(LayoutInflater.from( HomeActivity.this).inflate(R.layout.item_home, parent, false)); return holder; } @Override public void onBindViewHolder(MyViewHolder holder, int position) { holder.tv.setText(mDatas.get(position)); } @Override public int getItemCount() { return mDatas.size(); } class MyViewHolder extends ViewHolder { TextView tv; public MyViewHolder(View view) { super(view); tv = (TextView) view.findViewById(R.id.id_num); } }}如上,即就是Adapter的写法。其中的ViewHolder就是拿来负责View的回收和复用的,这样就不需要我们自己写完ViewHolder之后,还要在getView(int position, View convertView, ViewGroup parent)里一顿判断,一顿绑定,一顿find了。而且这里的ViewHolder成为了RecyclerView中必须继承的一部分,重写完后就需要放入 RecyclerView.Adapter< >这里来对基类的范型初始化。在这里,Recyclerview已经为你封装好了: getItemCount()就不必多说了,和ListView是一样的 getItemViewType(int position)是用来根据position的不同来实现RecyclerView中对不同布局的要求。从这个方法中所返回的值会在onCreateViewHolder中用到。比如头部,尾部,等等的特殊itemView(这里说成ViewHolder比较好)都可以在这里进行判断。 onCreateViewHolder(ViewGroup parent, int viewType)是用来配合写好的ViewHolder来返回一个ViewHolder对象。这里也涉及到了条目布局的加载。viewType则表示需要给当前position生成的是哪一种ViewHolder,这个参数也说明了RecyclerView对多类型ItemView的支持。 onBindViewHolder(MyViewHolder holder, int position)专门用来绑定ViewHolder里的控件和数据源中position位置的数据。这里,会有人问,那么item的子控件findViewById 去哪儿了?我们把它交给了ViewHolder的构造方法(其他方法也可以),它的本质是在onCreateViewHolder方法里生成ViewHolder的时候执行的。提升:1.代码重构:在上边看了这么多,有木有觉得,ViewHolder的功能并不是非常明确?它既负责了子控件的查询,又负责了子控件的装载工作。而布局加载和数据绑定却交给了Adapter......我们来看看掘金的做法:首先,它把Adapter和ViewHolder的功能以一种较为低耦合的方式进行了职能分离,让ViewHolder里所有的逻辑代码全部都只出现在ViewHolder中。我们现在就对前边提到的代码进行重构:ViewHodler:class MyViewHolder extends ViewHolder{ TextView tv; public MyViewHolder(Context context, View view){ super(view); tv = (TextView) view.findViewById(R.id.id_num); //当然,我们也可以在这里使用view来对RecyclerView的一个item进行事件监听,也可以使用 //tv等子控件来实现item的子控件的事件监听。这也是我之所以要传context的原因之一呢~ ...... } public static MyViewHolder newInstance(Activity context, ViewGroup parent){ View view = LayoutInflater.from( context).inflate(R.layout.item_home, parent,false); return new MyViewHolder(context, view); } } //你没看错,数据绑定也被整合进来了, //将adapter里的数据根据position获取到后传进来。当然,也可以根据具体情况来做调整。 public void onBinViewHolder(String data){ tv.setText(data);//既然这里也有子控件,那么这里也可以做item子控件的事件监听喽}RecyclerView:class HomeAdapter extends RecyclerView.Adapter<MyViewHolder>{ @Override public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType){//如需要,还要对viewType做判断 return MyViewHolder.newInstance(this, parent) } @Override public void onBindViewHolder(MyViewHolder holder, int position){ holder.onBindViewHolder(mDatas.get(position)); } @Override public int getItemCount(){ return mDatas.size(); }}抽取一个条目点击事件,让它更像ListView:class HomeAdapter extends RecyclerView.Adapter<MyViewHolder>{ private OnItemClickListener mOnItemClickListener; public void setOnItemClickLitener(OnItemClickLitener mOnItemClickLitener) { this.mOnItemClickLitener = mOnItemClickLitener; } @Override public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType){//如需要,还要对viewType做判断 return MyViewHolder.newInstance(this, parent) } @Override public void onBindViewHolder(MyViewHolder holder, int position){ holder.onBindViewHolder(mDatas.get(position)); //如果设置了回调,则设置点击事件 if (mOnItemClickLitener != null) { viewHolder.itemView.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { mOnItemClickLitener.onItemClick(viewHolder.itemView, i); } }); } } @Override public int getItemCount(){ return mDatas.size(); } public interface OnItemClickLitener { void onItemClick(View view, int position); } }接口调用 mAdapter.setOnItemClickLitener(new OnItemClickLitener() { @Override public void onItemClick(View view, int position) { ...... } });2.External上边提到了控制item的间隔,可以使用addItemDecoration(ItemDecoration decor),不过里边的ItemDecoration是一个抽象类,需要自己去实现...这个问题,那我们来实际解决一下:这是羊神实现的一个子类package com.zhy.sample.demo_recyclerview;import android.content.Context;import android.content.res.TypedArray;import android.graphics.Canvas;import android.graphics.Rect;import android.graphics.drawable.Drawable;import android.support.v7.widget.LinearLayoutManager;import android.support.v7.widget.RecyclerView;import android.support.v7.widget.RecyclerView.State;import android.util.Log;import android.view.View;public class DividerItemDecoration extends RecyclerView.ItemDecoration { private static final int[] ATTRS = new int[]{ android.R.attr.listDivider }; public static final int HORIZONTAL_LIST = LinearLayoutManager.HORIZONTAL; public static final int VERTICAL_LIST = LinearLayoutManager.VERTICAL; private Drawable mDivider; private int mOrientation; public DividerItemDecoration(Context context, int orientation) { final TypedArray a = context.obtainStyledAttributes(ATTRS); mDivider = a.getDrawable(0); a.recycle(); setOrientation(orientation); } public void setOrientation(int orientation) { if (orientation != HORIZONTAL_LIST && orientation != VERTICAL_LIST) { throw new IllegalArgumentException("invalid orientation"); } mOrientation = orientation; } @Override public void onDraw(Canvas c, RecyclerView parent) { Log.v("recyclerview - itemdecoration", "onDraw()"); if (mOrientation == VERTICAL_LIST) { drawVertical(c, parent); } else { drawHorizontal(c, parent); } } public void drawVertical(Canvas c, RecyclerView parent) { final int left = parent.getPaddingLeft(); final int right = parent.getWidth() - parent.getPaddingRight(); final int childCount = parent.getChildCount(); for (int i = 0; i < childCount; i++) { final View child = parent.getChildAt(i); android.support.v7.widget.RecyclerView v = new android.support.v7.widget.RecyclerView(parent.getContext()); final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child .getLayoutParams(); final int top = child.getBottom() + params.bottomMargin; final int bottom = top + mDivider.getIntrinsicHeight(); mDivider.setBounds(left, top, right, bottom); mDivider.draw(c); } } public void drawHorizontal(Canvas c, RecyclerView parent) { final int top = parent.getPaddingTop(); final int bottom = parent.getHeight() - parent.getPaddingBottom(); final int childCount = parent.getChildCount(); for (int i = 0; i < childCount; i++) { final View child = parent.getChildAt(i); final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child .getLayoutParams(); final int left = child.getRight() + params.rightMargin; final int right = left + mDivider.getIntrinsicHeight(); mDivider.setBounds(left, top, right, bottom); mDivider.draw(c); } } @Override public void getItemOffsets(Rect outRect, int itemPosition, RecyclerView parent) { if (mOrientation == VERTICAL_LIST) { outRect.set(0, 0, 0, mDivider.getIntrinsicHeight()); } else { outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0); } }}然后就是为我们的RecyclerView实例添加分割线addItemDecoration(new DividerItemDecoration(this,DividerItemDecoration.VERTICAL_LIST));系统默认的分割线往往达不到我们产品和设计师的要求,怎么办呢?<item name="android:listDivider">@drawable/your_custom_divider</item>通过以上xml属性,将系统的listDivider设为自己画出来的分割线,只需要放在你对应activity的主题下即可。技巧:RecyclerView 滚动条的显示与隐藏<android.support.v7.widget.RecyclerView android:layout_width="match_parent" android:layout_height="match_parent" android:scrollbars="vertical" > </android.support.v7.widget.RecyclerView>纵向显示:android:scrollbars="vertical"横向显示:android:scrollbars="horizontal"隐藏:android:

焦点访谈

最新最热的文章

更多 >

COPYRIGHT (©) 2017 Copyright ©2017 365体育在线备用网址 网站地图

联系我们

827570882

扫描二维码分享到微信