常用布局小技巧-项目总结

/ 0评 / 0

LinearLayout添加分割线

在android3.0及后面的版本在LinearLayout里增加了个分割线属性,通过这个属性我们可以很简单的为LinearLayout设置分割线。

<!--分割线图片-->
android:divider="@drawable/shape"

<!--分割线位置-->
<!--middle 分割线位置在两个控件之间-->
<!--beginning 分割线位置在布局最上面-->
<!--end 分割线位置在布局最下面-->
android:showDividers="middle|beginning|end" 

<!--分割线宽度-->
android:dividerPadding="1dp"

分割线如果是图片那就直接使用图片就行,如果要使用颜色就必须使用shape来显示,直接使用颜色或Color是没有用的 使用shape的时候要注意设置size属性不设置宽高分割线就不会显示出来,如果使用line那填充颜色只能使用stroke来显示颜色。

自定义CheckBox的样式

默认的CheckBox的样式肯定不能满足我们的开发需求,所以我们可以使用selector标签来自定义我们的CheckBox。

check uncheck

  1. 在drawable文件夹下建立一个xml文件。
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/check" android:state_checked="true"/>
    <item android:drawable="@drawable/uncheck" android:state_checked="false"/>
    <item android:drawable="@drawable/uncheck"/>
</selector>
<CheckBox
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:button="@drawable/checkbox_selector"
    android:text="保存密码" />

这样就实现了自定义CheckBox。如下图

QQ图片20160409130333_看图王QQ图片20160409130319_看图王

TextView添加下划线

如果是在资源文件里,可以这样写

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="url_text"><u>没有注册?注册</u></string>
</resources>

在布局文件中使用

 <TextView 
        android:textSize="16sp"
        android:text="@string/url_text"
        android:textStyle="italic"
        android:textColor="@color/url_color"
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"/>

如果是代码这样写

TextView textView = (TextView)findViewById(R.id.testView);
textView.setText(Html.fromHtml("<u>" + "没有注册?注册" + "</u>" ));

页面轮换:ViewFlipper 和 ViewPager 的区别

ViewFlipper继承ViewAnimator,切换view的时候是有动画效果的,适合做ppt,多界面的程序欢迎引导界面,算是个轻量级的组件,适合展示静态数据,少量数据。

ViewPager继承ViewGroup。看官网描述,这货和Fragment是好搭档,Fragment有自己的生命周期。也就是说ViewPager更适用于复杂的视图切换,而且Viewpager有自己的adapter,这也让其适应复杂对象,实现数据的动态加载。

解决ViewPager和ViewFlipper嵌套冲突

项目中主界面是ViewPager实现的左右滑动,但是在某一个界面仍然有一个可左右滑动并且需要动画的ViewFlipper,发现滑动冲突了,于是重写了ViewFlipper来解决。

public class PageViewFlipper extends ViewFlipper {  

    public PageViewFlipper(Context context) {  
        super(context);  
    }  
  
    public PageViewFlipper(Context context, AttributeSet attrs) {  
        super(context, attrs);  
    }  
  
    @Override  
    public boolean dispatchTouchEvent(MotionEvent ev) {  
        getParent().requestDisallowInterceptTouchEvent(true);  
        super.dispatchTouchEvent(ev);  
        return true;  
    }  
}

参考链接

给Fragment传递参数

Fragment有下面的注意事项。

public Fragment ()

Default constructor. Every fragment must have an empty constructor, so it can be instantiated when restoring its activity's state. It is strongly recommended that subclasses do not have other constructors with parameters, since these constructors will not be called when the fragment is re-instantiated; instead, arguments can be supplied by the caller with setArguments(Bundle) and later retrieved by the Fragment with  getArguments()

Applications should generally not implement a constructor. The first place application code an run where the fragment is ready to be used is in onAttach(Activity), the point where the fragment is actually associated with its activity. Some applications may also want to implementonInflate(Activity, AttributeSet, Bundle) to retrieve attributes from a layout resource, though should take care here because this happens for the fragment is attached to its activity.

也就是说,官方不推荐给Fragment添加参数,而是推荐使用Fragment的setArguments(Bundle)为fragment设置参数,然后使用getArguments()取出参数。

例如:

public static final AlertFragment newInstance(int title, String message)
{
	AlertFragment f = new AlertFragment();
	Bundle bdl = new Bundle(2);
	bdl.putInt(EXTRA_TITLE, title);
	bdl.putString(EXTRA_MESSAGE, message);
	//使用setArguments设置参数
	f.setArguments(bdl);
	return f;
}

在Fragment中取出参数。

@Override
public void onCreate(Bundle savedInstanceState)
{
	title = getArguments().getInt(EXTRA_TITLE);
	message = getArguments().getString(EXTRA_MESSAGE);
	//...
	//etc
	//...
}

为控件设置上下左右的图片

两种方法:

优点:在xml中间中直接配置。简单。

缺点:图片大小不能设置,默认为图片自身的大小,显示的效果不容易设置。

优点:可以随意设置大小,效果控制简单。

缺点:在事件监听函数中通过代码来修改。

ps:如果是本身有按钮的控件,如RadioButton、CheckBox。必须先使用android:button="@null"消除自身的按钮,然后再设置

Drawable drawable = null;
drawable = getResources().getDrawable(R.drawable.btn_strip_mark_off);
//调用setCompoundDrawables时,必须调用Drawable.setBounds()方法,否则图片不显示
drawable.setBounds(0, 0, px为单位的值, px为单位的值);
btn.setCompoundDrawables(img_off, null, null, null); //设置左图标

通过setCompoundDrawablePadding(int padding)方法何以设置drawable和text之间的间距。

new Handler()和new Handler(Looper.getMainLooper())的区别

在开发过程中,我们往往用到Handler来进行新线程与主线程的通信,一般来说,初始化一个handler有以下两种方法

Handler handler = new Handler();

Handler handler = new Handler(Looper.getMainLooper());

第一种不带参数的实例化会默认用当前线程的looper,第二种使用主线程的Lopper来初始化Handler

Looper.getMainLooper()是获取主线程的Looper对象  Returns the application's main looper, which lives in the main thread of the application.

情况:

1.要刷新UI,handler要使用主线程的looper初始化。那么在主线程中使用 Handler handler = new Handler();然后将其当参数传递给新线程,如果在其他线程,也要满足这个功能的话,可以使用Handler handler = new Handler(Looper.getMainLooper());

2.不用刷新ui,只是处理消息。 当前线程如果是主线程的话,Handler handler = new Handler();不是主线程的话,需要使用如下形式。

Looper.prepare();

Handler handler = new Handler();

Looper.loop();

或者Handler handler = new Handler(Looper.getMainLooper());若是实例化的时候用Looper.getMainLooper()就表示放到主UI线程去处理。如果不是的话,因为只有UI线程默认Loop.prepare();Loop.loop();过,其他线程需要手动调用这两个,否则会报错。

参考链接

自定义view初始化和销毁的时机

我们在自定义view的过程中经常会启动一些后台线程或者其他延时操作,这就要求我们在view的附属被销毁(Activity退出)的时候将一些后台操作给停止掉,View中有两个回调方法分别对应着View的显示和销毁。

onAttachedToWindow 在这个里面可以进行初始化
onDetachedFromWindow 在这个里面进行回收/销毁工作

在后台线程中操作主线程

有时候我们在Activity中进行一个后台操作,需要将结果显示到界面上的时候,如果图方便,可以使用Activity的void android.app.Activity.runOnUiThread(Runnable action)方法。

new Thread(new Runnable() {

    @Override
    public void run() {

        while (true) {
            //在这里后台线程执行操作
            SystemClock.sleep(500);
            MainActivity.this.runOnUiThread(new Runnable() {

                @Override
                public void run() {
                    //主线程显示结果
                }
            });
        }
    }
}).start();

其他

Activity里面的finish()方法执行以后会继续执行下面未执行的代码,直到执行完毕以后才调用onDestory()方法

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注