Android开发中RecyclerView简单使用

 更新时间:2016年10月2日 16:24  点击:2218
RecyclerView是一个比ListView更灵活的一个控件,以后可以直接抛弃ListView了,据官方的介绍,该控件用于在有限的窗口中展示大量数据集,其实这样功能的控件我们并不陌生,例如:ListView、GridView,下面我们就来看小编整理的一篇关于RecyclerView简单使用


那么有了ListView、GridView为什么还需要RecyclerView这样的控件呢?整体上看RecyclerView架构,提供了一种插拔式的体验,高度的解耦,异常的灵活,通过设置它提供的不同LayoutManager,ItemDecoration , ItemAnimator实现令人瞠目的效果。

你想要控制其显示的方式,请通过布局管理器LayoutManager
你想要控制Item间的间隔(可绘制),请通过ItemDecoration
你想要控制Item增删的动画,请通过ItemAnimator
你想要控制点击、长按事件,请自己写(擦,这点尼玛。)

每个item的布局如下:


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:id="@+id/recycler_view_test_item_person_view"
              android:orientation="vertical"
              android:layout_width="match_parent"
              android:layout_height="wrap_content"
              android:padding="15dp"
              android:background="#aabbcc"
        >
    <TextView
            android:id="@+id/recycler_view_test_item_person_name_tv"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:textSize="18sp"
            android:background="#ccbbaa"
            />
    <TextView
            android:id="@+id/recycler_view_test_item_person_age_tv"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:paddingLeft="5dp"
            android:background="#aaccbb"
            android:textSize="15sp"
            />
</LinearLayout>

item的布局很简单,只有两个TextView,一个用来显示名字,一个用来显示年龄。

Person的实体类就不贴代码了,两个属性:名字和年龄。

然后需要使用到RecyclerView,所以需要把support v7添加到class path,并在布局中添加该控件:


<android.support.v7.widget.RecyclerView
                android:id="@+id/recycler_view_test_rv"
                android:scrollbars="vertical"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:background="#bbccaa"
                />

然后在onCreate中:


1         recyclerView.setHasFixedSize(true);
2
3         RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(context);
4         recyclerView.setLayoutManager(layoutManager);
5
6         initData();
7         adapter = new PersonAdapter(personList);
8         adapter.setOnRecyclerViewListener(this);
9         recyclerView.setAdapter(adapter);   

 

如上述代码:

Line1: 使RecyclerView保持固定的大小,这样会提高RecyclerView的性能。

Line3: LinearLayoutManager,如果你需要显示的是横向滚动的列表或者竖直滚动的列表,则使用这个LayoutManager。显然,我们要实现的是ListView的效果,所以需要使用它。生成这个LinearLayoutManager之后可以设置他滚动的方向,默认竖直滚动,所以这里没有显式地设置。

Line6: 初始化数据源。

Line7~9: 跟ListView一样,需要设置RecyclerView的Adapter,但是这里的Adapter跟ListView使用的Adapter不一样,这里的Adapter需要继承RecyclerView.Adapter,需要实现3个方法:

- onCreateViewHolder()

- onBindViewHolder()

- getItemCount()

直接看代码:


 1 package com.wangjie.helloandroid.sample.recycler.person;
 2
 3 import android.support.v7.widget.RecyclerView;
 4 import android.view.LayoutInflater;
 5 import android.view.View;
 6 import android.view.ViewGroup;
 7 import android.widget.LinearLayout;
 8 import android.widget.TextView;
 9 import com.wangjie.androidbucket.log.Logger;
10 import com.wangjie.helloandroid.R;
11
12 import java.util.List;
13
14 /**
15  * Author: wangjie
16  * Email: tiantian.china.2@gmail.com
17  * Date: 1/17/15.
18  */
19 public class PersonAdapter extends RecyclerView.Adapter {
20     public static interface OnRecyclerViewListener {
21         void onItemClick(int position);
22         boolean onItemLongClick(int position);
23     }
24
25     private OnRecyclerViewListener onRecyclerViewListener;
26
27     public void setOnRecyclerViewListener(OnRecyclerViewListener onRecyclerViewListener) {
28         this.onRecyclerViewListener = onRecyclerViewListener;
29     }
30
31     private static final String TAG = PersonAdapter.class.getSimpleName();
32     private List<Person> list;
33
34     public PersonAdapter(List<Person> list) {
35         this.list = list;
36     }
37
38     @Override
39     public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
40         Logger.d(TAG, "onCreateViewHolder, i: " + i);
41         View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.recycler_view_test_item_person, null);
42         LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
43         view.setLayoutParams(lp);
44         return new PersonViewHolder(view);
45     }
46
47     @Override
48     public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int i) {
49         Logger.d(TAG, "onBindViewHolder, i: " + i + ", viewHolder: " + viewHolder);
50         PersonViewHolder holder = (PersonViewHolder) viewHolder;
51         holder.position = i;
52         Person person = list.get(i);
53         holder.nameTv.setText(person.getName());
54         holder.ageTv.setText(person.getAge() + "岁");
55     }
56
57     @Override
58     public int getItemCount() {
59         return list.size();
60     }
61
62     class PersonViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener
63     {
64         public View rootView;
65         public TextView nameTv;
66         public TextView ageTv;
67         public int position;
68
69         public PersonViewHolder(View itemView) {
70             super(itemView);
71             nameTv = (TextView) itemView.findViewById(R.id.recycler_view_test_item_person_name_tv);
72             ageTv = (TextView) itemView.findViewById(R.id.recycler_view_test_item_person_age_tv);
73             rootView = itemView.findViewById(R.id.recycler_view_test_item_person_view);
74             rootView.setOnClickListener(this);
75             rootView.setOnLongClickListener(this);
76         }
77
78         @Override
79         public void onClick(View v) {
80             if (null != onRecyclerViewListener) {
81                 onRecyclerViewListener.onItemClick(position);
82             }
83         }
84
85         @Override
86         public boolean onLongClick(View v) {
87             if(null != onRecyclerViewListener){
88                 return onRecyclerViewListener.onItemLongClick(position);
89             }
90             return false;
91         }
92     }
93
94 }

如上代码所示:

public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i)

这个方法主要生成为每个Item inflater出一个View,但是该方法返回的是一个ViewHolder。方法是把View直接封装在ViewHolder中,然后我们面向的是ViewHolder这个实例,当然这个ViewHolder需要我们自己去编写。直接省去了当初的convertView.setTag(holder)和convertView.getTag()这些繁琐的步骤。

 

public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int i)

这个方法主要用于适配渲染数据到View中。方法提供给你了一个viewHolder,而不是原来的convertView。

对比下以前的写法就一目了然了:


 1 @Override
 2     public View getView(int position, View convertView, ViewGroup parent) {
 3         ViewHolder holder;
 4         if(null == convertView){
 5             holder = new ViewHolder();
 6             LayoutInflater mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
 7             convertView = mInflater.inflate(R.layout.item, null);
 8             holder.btn = (Button) convertView.findViewById(R.id.btn);
 9             holder.tv = (TextView) convertView.findViewById(R.id.tv);
10             holder.iv = (TextView) convertView.findViewById(R.id.iv);
11
12             convertView.setTag(holder);
13         }else{
14             holder = (ViewHolder) convertView.getTag();
15         }
16         final HashMap<String, Object> map = list.get(position);
17
18         holder.iv.setImageResource(Integer.valueOf(map.get("iv").toString()));
19         holder.tv.setText(map.get("tv").toString());
20
21         holder.btn.setOnClickListener(new View.OnClickListener() {
22             @Override
23             public void onClick(View v) {
24                 Toast.makeText(context, map.get("btn").toString(), Toast.LENGTH_SHORT).show();
25             }
26         });
27
28         return convertView;
29     }
30
31     class ViewHolder{
32         Button btn;
33         ImageView iv;
34         TextView tv;
35
36     }

对比后可以发现:

旧的写法中Line5~Line12+Line28部分的代码其实起到的作用相当于新的写法的onCreateViewHolder();

旧的写法中Line14~Line26部分的代码其实起到的作用相当于新的写法的onBindViewHolder();

既然是这样,那我们就把原来相应的代码搬到对应的onCreateViewHolder()和onBindViewHolder()这两个方法中就可以了。

因为RecyclerView帮我们封装了Holder,所以我们自己写的ViewHolder就需要继承RecyclerView.ViewHolder,只有这样,RecyclerView才能帮你去管理这个ViewHolder类。

既然getView方法的渲染数据部分的代码相当于onBindViewHolder(),所以如果调用adapter.notifyDataSetChanged()方法,应该也会重新调用onBindViewHolder()方法才对吧?实验后,果然如此!

除了adapter.notifyDataSetChanged()这个方法之外,新的Adapter还提供了其他的方法,如下:


        public final void notifyDataSetChanged()
        public final void notifyItemChanged(int position)
        public final void notifyItemRangeChanged(int positionStart, int itemCount)
        public final void notifyItemInserted(int position)
        public final void notifyItemMoved(int fromPosition, int toPosition)
        public final void notifyItemRangeInserted(int positionStart, int itemCount)
        public final void notifyItemRemoved(int position)
        public final void notifyItemRangeRemoved(int positionStart, int itemCount)

基本上看到方法的名字就知道这个方法是干嘛的了,

第一个方法没什么好讲的,跟以前一样。

notifyItemChanged(int position),position数据发生了改变,那调用这个方法,就会回调对应position的onBindViewHolder()方法了,当然,因为ViewHolder是复用的,所以如果position在当前屏幕以外,也就不会回调了,因为没有意义,下次position滚动会当前屏幕以内的时候同样会调用onBindViewHolder()方法刷新数据了。其他的方法也是同样的道理。

public final void notifyItemRangeChanged(int positionStart, int itemCount),顾名思义,可以刷新从positionStart开始itemCount数量的item了(这里的刷新指回调onBindViewHolder()方法)。

public final void notifyItemInserted(int position),这个方法是在第position位置被插入了一条数据的时候可以使用这个方法刷新,注意这个方法调用后会有插入的动画,这个动画可以使用默认的,也可以自己定义。

public final void notifyItemMoved(int fromPosition, int toPosition),这个方法是从fromPosition移动到toPosition为止的时候可以使用这个方法刷新

public final void notifyItemRangeInserted(int positionStart, int itemCount),显然是批量添加。

public final void notifyItemRemoved(int position),第position个被删除的时候刷新,同样会有动画。

public final void notifyItemRangeRemoved(int positionStart, int itemCount),批量删除。

 

这些方法分析完之后,我们来实现一个点击一个按钮,新增一条数据,长按一个item,删除一条数据的场景。

以下是新增一条数据的代码:

1 Person person = new Person(i, "WangJie_" + i, 10 + i);
2 adapter.notifyItemInserted(2);
3 personList.add(2, person);
4 adapter.notifyItemRangeChanged(2, adapter.getItemCount());
如上代码:

Line2:表示在position为2的位置,插入一条数据,这个时候动画开始执行。

Line3: 表示在数据源中position为2的位置新增一条数据(其实这个才是真正的新增数据啦)。

Line4: 为什么要刷新position为2以后的数据呢?因为,在position为2的位置插入了一条数据后,新数据的position变成了2,那原来的position为2的应该变成了3,3的应该变成了4,所以2以后的所有数据的position都发生了改变,所以需要把position2以后的数据都要刷新。理论上是这样,但是实际上刷新的数量只有在屏幕上显示的position为2以后的数据而已。如果这里使用notifyDataSetChanged()来刷新屏幕上显示的所有item可以吗?结果不会出错,但是会有一个问题,前面调用了notifyItemInserted()方法后会在执行动画,如果你调用notifyDataSetChanged()刷新屏幕上显示的所有item的话,必然也会刷新当前正在执行动画的那个item,这样导致的结果是,前面的动画还没执行完,它马上又被刷新了,动画就看不见了。所以只要刷新2以后的item就可以了。

 

看了RecyclerView的api,发现没有setOnItemClickListener--,所以还是自己把onItemClick从Adapter中回调出来吧。这个很简单,就像上面PersonAdaper中写的OnRecyclerViewListener那样。

 

长按删除的代码如下:

1 adapter.notifyItemRemoved(position);
2 personList.remove(position);
3 adapter.notifyItemRangeChanged(position, adapter.getItemCount());
代码跟之前插入的代码基本一致。先通知执行动画,然后删除数据源中的数据,然后通知position之后的数据刷新就可以了。

这样ListView的效果就实现了。

RecycleView的出现方便了我们自定义合适的布局,几行代码可以变换多种状态——listView、gridView、瀑布流等,下面简单介绍如何编写adapter的相关代码

 
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.TextView;
 
import com.squareup.picasso.Picasso;
 
import java.util.List;
 
 
/**
 * Created by abel on 16/4/21.
 */
public class RecycleViewAdapter extends RecyclerView.Adapter<RecycleViewAdapter.MyHolder> {
    private LayoutInflater mInflater;
    private List<CollectionEntity> list;
    private Context context;
    OnItemClickListener onItemClickListener;
    /*
       获取数据源
     */
    public RecycleViewAdapter(Context context, List<CollectionEntity> list) {
        this.mInflater = LayoutInflater.from(context);
        this.list = list;
        this.context = context;
    }
    /*
    加载item布局
     */
    @Override
    public MyHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        MyHolder myHolder = new MyHolder(mInflater.inflate(R.layout.item_collection, parent, false));
 
        return myHolder;
    }
 
    /**
     * 绑定数据
     * @param holder item
     * @param position position
     */
    @Override
    public void onBindViewHolder(final MyHolder holder, int position) {
        CollectionEntity collectionEntity = list.get(position);
        holder.tv_already_pay.setText("已售" + SpannableStringUtil.checkNull(1, collectionEntity.getAlreadyPay()));
        holder.tv_newMoney.setText("¥" + SpannableStringUtil.checkNull(1, collectionEntity.getNewMoney()));
        holder.tv_oldMoney.setText(SpannableStringUtil.addDeleteLineSpanTwo("¥" + SpannableStringUtil.checkNull(1, collectionEntity.getOldMoney())));
        if (collectionEntity.getPic() != null) {
            Picasso.with(context).load(Url.IMAGR_ROOT + collectionEntity.getPic())
                    .tag("bitmap")
                    .placeholder(R.mipmap.pic_common_carlogo_loading)
                    .into(holder.userpic);
        }
        if (onItemClickListener != null) {
            if (!holder.itemView.hasOnClickListeners()) {
                holder.itemView.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        onItemClickListener.onItemClick(v, holder.getAdapterPosition());
                    }
                });
            }
        }
    }
 
    @Override
    public int getItemCount() {
        return list.size();
    }
 
    /**
     * 点击事件接口
     */
    public interface OnItemClickListener {
        void onItemClick(View view, int postion);
    }
 
    public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
        this.onItemClickListener = onItemClickListener;
    }
 
    /**
     * viewHolder
     */
    public class MyHolder extends RecyclerView.ViewHolder {
        private ImageView userpic;
        private TextView tv_title, tv_newMoney, tv_oldMoney, tv_already_pay;
        private LinearLayout ll_root;
 
        public MyHolder(View itemView) {
            super(itemView);
            userpic = (ImageView) itemView.findViewById(R.id.img_userpic);
            tv_title = (TextView) itemView.findViewById(R.id.tv_collection_title);
            tv_newMoney = (TextView) itemView.findViewById(R.id.tv_now_price);
            tv_already_pay = (TextView) itemView.findViewById(R.id.tv_already_sell);
            ll_root = (LinearLayout) itemView.findViewById(R.id.ll_root);
            tv_oldMoney = (TextView) itemView.findViewById(R.id.tv_old_price);
        }
    }
}

由于recycleView没有提供点击事件监听,所以需要我们自己去实现,上面的接口就是对外公布的点击事件,在activity中需要加上

mRecyView.setLayoutManager(new LinearLayoutManager(this));

来设置管理器达到listView与gridView的效果

Toolbar是android L引入的一个新控件,可以理解为action bar的第二代:提供了action bar类似的功能,但是更灵活。

不像actionbar那么固定,Toolbar更像是一般的View元素,可以被放置在view树体系的任意位置,可以应用动画,可以跟着scrollView滚动,可以与布局中的其他view交互。当然,你还可以用Toolbar替换掉actionbar,只需调用 Activity.setActionBar()。

虽然toolbar已经出来很长时间,但还是有些必要再进行简单介绍,

先上布局

<android.support.design.widget.AppBarLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:theme="@style/AppTheme.AppBarOverlay">
 
    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="?attr/colorPrimary"
        app:theme="@style/AppTheme.AppBarOverlay"
        >
        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_centerInParent="true"
            android:layout_marginLeft="15dp"
            android:background="@mipmap/icon_index_search" />
 
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:text="搜索"
            android:textColor="#956C28"
            android:textSize="16sp" />
 
 
 
        </android.support.v7.widget.Toolbar>
 
</android.support.design.widget.AppBarLayout>
屏幕快照 2016-04-22 16.38.12

上面的布局呈现的是这种效果,可以在里面进行自定义,也可以通过menu进行控件的编写,如果需要在滑动的时候隐藏toolbar就需要在外面包裹一层APPBarLayout


<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <item
        android:id="@+id/action_location"
        android:orderInCategory="0"
        android:title="定位"
        android:icon="@mipmap/icon_index_location"
        app:showAsAction="ifRoom" />
 
 
</menu>
在这里可以指定toolbar显示哪些控件,app:showAsAction的属性可以指定该图标是显示在toolbar上还是显示在菜单里,大家可以自行测试,

下面进入核心代码部分,

Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
toolbar.setNavigationIcon(R.mipmap.icon_index_menu);
setSupportActionBar(toolbar);

可以通过toolbar对象来设置我们需要的结果,例如icon,标题,副标题等等,


@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
}
 
@Override
public boolean onOptionsItemSelected(MenuItem item) {
    int id = item.getItemId();
    if (id == R.id.action_location) {
 
        return true;
    }
 
    return super.onOptionsItemSelected(item);
}
重写上述两个方法进行toolbar上的菜单按钮加载,然后设置监听,到此就结束了。下面说一下需要注意的地方,在布局文件中也可以设置icon、title等,但是需要加入自定义属性的命名空间


<pre class="hljs xml"><code class="xml">xmlns:toolbar="http://schemas.android.com/apk/res-auto"</code>

然后通过toolbar:title=””来设置各种属性。

本文章为各位介绍一篇关于Android自定义TextView实现无限制跑马灯效果,希望文章能够帮助到各位朋友,有兴趣的朋友可以一起来看看吧。

在做APP开发的时候,有些标题需要实现跑马灯的效果,如果使用系统自带的TextView实现这样的效果,只需要在TextView的属性中添加如下代码:

android:ellipsize="marquee"//跑马灯效果
android:marqueeRepeatLimit="marquee_forever"//无限制不间断显示
android:singleLine="true"//单行显示

但是这样子有一个致命的缺点,就是这种状态的跑马灯只能在TextView处于焦点状态的时候,它才会滚动,对于APP实际的开发应用中很不实用,因为它不可能一直都处于获取焦点状态。

为了是跑马灯无论在什么情况下都能跑起来,达到我们想要的效果,我们需要自定义一个TextView继承TextView,并且重写isFocuse()方法,让它永远返回true,这样跑马灯效果就能一直的跑起来了。

代码如下:

package zm.marqueetextview;

import android.content.Context;
import android.util.AttributeSet;
import android.widget.TextView;

public class MarqueeTextView extends TextView {

    public MarqueeTextView(Context context) {
        super(context);
    }

    public MarqueeTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public MarqueeTextView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    public boolean isFocused() {
        return true;
    }
}

然后直接在布局文件中引用即可:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="15dp">

    <zm.marqueetextview.MarqueeTextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:singleLine="true"
        android:ellipsize="marquee"
        android:marqueeRepeatLimit="marquee_forever"
        android:text="这是一个自定义的带有跑马灯效果的TextView这是一个自定义的带有跑马灯效果的TextView" />

</RelativeLayout>

RelativeLayout控件在android开发应用到非常的多了,下文我们就来看一篇关于Android动态设置RelativeLayout控件的高度例子,具体的代码如下所示。

在做项目的时候,其中一个需求是要求banner图的宽和高是1:1,所以我需要获取手机屏幕的宽度,然后动态的把高度值设置为手机屏幕宽度的值,在这项目中就是设置RelativeLayout的高度值,代码如下:

mRllayoutBanner = (RelativeLayout) findViewById(R.id.rl_banner);
WindowManager wm = this.getWindowManager();
int width = wm.getDefaultDisplay().getWidth();//获取屏幕宽度
android.view.ViewGroup.LayoutParams pp = mRllayoutBanner.getLayoutParams();
mRllayoutBanner.getLayoutParams();
pp.height = width;
mRllayoutBanner.setLayoutParams(pp);//把banner图的高度设为此宽度值


当然,其中的width也可以是其他int值,这样就实现了动态设置RelativeLayout的高度。

RelativeLayout用到的一些重要的属性:

第一类:属性值为true或false
android:layout_centerHrizontal 水平居中
android:layout_centerVertical 垂直居中
android:layout_centerInparent 相对于父元素完全居中
android:layout_alignParentBottom 贴紧父元素的下边缘
android:layout_alignParentLeft 贴紧父元素的左边缘
android:layout_alignParentRight 贴紧父元素的右边缘
android:layout_alignParentTop 贴紧父元素的上边缘
android:layout_alignWithParentIfMissing 如果对应的兄弟元素找不到的话就以父元素做参照物
第二类:属性值必须为id的引用名“@id/id-name”
android:layout_below 在某元素的下方
android:layout_above 在某元素的的上方
android:layout_toLeftOf 在某元素的左边
android:layout_toRightOf 在某元素的右边
android:layout_alignTop 本元素的上边缘和某元素的的上边缘对齐
android:layout_alignLeft 本元素的左边缘和某元素的的左边缘对齐
android:layout_alignBottom 本元素的下边缘和某元素的的下边缘对齐
android:layout_alignRight 本元素的右边缘和某元素的的右边缘对齐
第三类:属性值为具体的像素值,如30dip,40px
android:layout_marginBottom 离某元素底边缘的距离
android:layout_marginLeft 离某元素左边缘的距离
android:layout_marginRight 离某元素右边缘的距离
android:layout_marginTop 离某元素上边缘的距离

EditText的android:hint
设置EditText为空时输入框内的提示信息。
android:gravity 
android:gravity属性是对该view 内容的限定.比如一个button 上面的text. 你可以设置该text 在view的靠左,靠右等位置.以button为例,android:gravity="right"则button上面的文字靠右
android:layout_gravity
android:layout_gravity是用来设置该view相对与起父view 的位置.比如一个button 在linearlayout里,你想把该button放在靠左、靠右等位置就可以通过该属性设置.以button为例,android:layout_gravity="right"则button靠右

android:layout_alignParentRight
使当前控件的右端和父控件的右端对齐。这里属性值只能为true或false,默认false。
android:scaleType:
android:scaleType是控制图片如何resized/moved来匹对ImageView的size。ImageView.ScaleType / android:scaleType值的意义区别:
CENTER /center 按图片的原来size居中显示,当图片长/宽超过View的长/宽,则截取图片的居中部分显示
CENTER_CROP / centerCrop 按比例扩大图片的size居中显示,使得图片长(宽)等于或大于View的长(宽)
CENTER_INSIDE / centerInside 将图片的内容完整居中显示,通过按比例缩小或原来的size使得图片长/宽等于或小于View的长/宽
FIT_CENTER / fitCenter 把图片按比例扩大/缩小到View的宽度,居中显示
FIT_END / fitEnd 把图片按比例扩大/缩小到View的宽度,显示在View的下部分位置
FIT_START / fitStart 把图片按比例扩大/缩小到View的宽度,显示在View的上部分位置
FIT_XY / fitXY 把图片不按比例扩大/缩小到View的大小显示
MATRIX / matrix 用矩阵来绘制,动态缩小放大图片来显示。
** 要注意一点,Drawable文件夹里面的图片命名是不能大写的。

BottomNavigationBar的例子小编网上找了一下不少哦,下面给各位整理了一篇关于BottomNavigationBar的使用例子,具体的如下所示。

这次写个新的底部栏实现方式,BottomNavigationBar,貌似上个月谷歌发布的,使用起来也很方便下面简单介绍下使用方式,

1、compile ‘com.ashokvarma.android:bottom-navigation-bar:0.9.5’     在gradle中加入这句

2、布局文件


<pre><?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.chenxu.mybottomdemo.MainActivity">
<LinearLayout
    android:id="@+id/ll_root"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_above="@+id/bottom_bar"
    />
    <com.ashokvarma.bottomnavigation.BottomNavigationBar
        android:id="@+id/bottom_bar"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:layout_alignParentBottom="true" />
 
</RelativeLayout></pre>

3、Java代码


<pre>package com.example.chenxu.mybottomdemo;
 
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
 
import com.ashokvarma.bottomnavigation.BottomNavigationBar;
import com.ashokvarma.bottomnavigation.BottomNavigationItem;
 
 
public class MainActivity extends AppCompatActivity implements BottomNavigationBar.OnTabSelectedListener {
    private BottomNavigationBar mBottomBar;
    private FragmentOne fragmentOne;
    private FragmentTwo fragmentTwo;
    private FragmentThree fragmentThree;
    private FragmentFore fragmentFore;
    private FragmentFive fragmentFive;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        assignViews();
    }
 
    /**
     * 添加页面
     */
    private void assignViews() {
        mBottomBar = (BottomNavigationBar) findViewById(R.id.bottom_bar);
        mBottomBar.addItem(new BottomNavigationItem(R.mipmap.ic_launcher, "首页"))
                .addItem(new BottomNavigationItem(R.mipmap.ic_launcher, "商品"))
                .addItem(new BottomNavigationItem(R.mipmap.ic_launcher, "分类"))
                .addItem(new BottomNavigationItem(R.mipmap.ic_launcher, "购物车"))
                .addItem(new BottomNavigationItem(R.mipmap.ic_launcher, "我的"))
                .initialise();
        mBottomBar.setTabSelectedListener(this);//设置监听
        setDefaultFragment();//设置默认选项
    }
    private void setDefaultFragment() {
        FragmentManager fragmentManager=getSupportFragmentManager();
        FragmentTransaction fragmentTransaction=fragmentManager.beginTransaction();
        hideFragments(fragmentTransaction);
        fragmentOne=new FragmentOne();
        fragmentTransaction.add(R.id.ll_root,fragmentOne);
        fragmentTransaction.commit();
    }
 
    /**
     * 隐藏fragment
     * @param transaction
     */
    private void hideFragments(FragmentTransaction transaction) {
        if (fragmentOne != null) {
            transaction.hide(fragmentOne);
        }
        if (fragmentTwo != null) {
            transaction.hide(fragmentTwo);
        }
        if (fragmentThree != null) {
            transaction.hide(fragmentThree);
        }
        if (fragmentFore != null) {
            transaction.hide(fragmentFore);
        }
        if (fragmentFive != null) {
            transaction.hide(fragmentFive);
        }
    }
 
    @Override
    public void onTabSelected(int position) {
        FragmentManager fragmentManager=getSupportFragmentManager();
        FragmentTransaction fragmentTransaction=fragmentManager.beginTransaction();
        hideFragments(fragmentTransaction);
        switch (position){
            case 0:
                if (fragmentOne==null){
                    fragmentOne=new FragmentOne();
                    fragmentTransaction.add(R.id.ll_root,fragmentOne);
 
                }else {
                    fragmentTransaction.show(fragmentOne);
                }
                break;
            case 1:
                if (fragmentTwo==null){
                    fragmentTwo=new FragmentTwo();
                    fragmentTransaction.add(R.id.ll_root,fragmentTwo);
 
                }else {
                    fragmentTransaction.show(fragmentTwo);
                }
                break;
            case 2:
                if (fragmentThree==null){
                    fragmentThree=new FragmentThree();
                    fragmentTransaction.add(R.id.ll_root,fragmentThree);
 
                }else {
                    fragmentTransaction.show(fragmentThree);
                }
                break;
            case 3:
                if (fragmentFore==null){
                    fragmentFore=new FragmentFore();
                    fragmentTransaction.add(R.id.ll_root,fragmentFore);
 
                }else {
                    fragmentTransaction.show(fragmentFore);
                }
                break;
            case 4:
                if (fragmentFive==null){
                    fragmentFive=new FragmentFive();
                    fragmentTransaction.add(R.id.ll_root,fragmentFive);
 
                }else {
                    fragmentTransaction.show(fragmentFive);
                }
                break;
        }
        fragmentTransaction.commit();
    }
 
    @Override
    public void onTabUnselected(int position) {
 
    }
 
    @Override
    public void onTabReselected(int position) {
 
    }
}</pre>

注:每个底部按钮对应一个fragment即可,以上就是全部内容,用起来效果不错,推荐使用

[!--infotagslink--]

相关文章

  • 图解PHP使用Zend Guard 6.0加密方法教程

    有时为了网站安全和版权问题,会对自己写的php源码进行加密,在php加密技术上最常用的是zend公司的zend guard 加密软件,现在我们来图文讲解一下。 下面就简单说说如何...2016-11-25
  • Android子控件超出父控件的范围显示出来方法

    下面我们来看一篇关于Android子控件超出父控件的范围显示出来方法,希望这篇文章能够帮助到各位朋友,有碰到此问题的朋友可以进来看看哦。 <RelativeLayout xmlns:an...2016-10-02
  • ps怎么使用HSL面板

    ps软件是现在很多人都会使用到的,HSL面板在ps软件中又有着非常独特的作用。这次文章就给大家介绍下ps怎么使用HSL面板,还不知道使用方法的下面一起来看看。 &#8195;...2017-07-06
  • Plesk控制面板新手使用手册总结

    许多的朋友对于Plesk控制面板应用不是非常的了解特别是英文版的Plesk控制面板,在这里小编整理了一些关于Plesk控制面板常用的使用方案整理,具体如下。 本文基于Linu...2016-10-10
  • 使用insertAfter()方法在现有元素后添加一个新元素

    复制代码 代码如下: //在现有元素后添加一个新元素 function insertAfter(newElement, targetElement){ var parent = targetElement.parentNode; if (parent.lastChild == targetElement){ parent.appendChild(newEl...2014-05-31
  • Android开发中findViewById()函数用法与简化

    findViewById方法在android开发中是获取页面控件的值了,有没有发现我们一个页面控件多了会反复研究写findViewById呢,下面我们一起来看它的简化方法。 Android中Fin...2016-09-20
  • Android模拟器上模拟来电和短信配置

    如果我们的项目需要做来电及短信的功能,那么我们就得在Android模拟器开发这些功能,本来就来告诉我们如何在Android模拟器上模拟来电及来短信的功能。 在Android模拟...2016-09-20
  • 使用GruntJS构建Web程序之构建篇

    大概有如下步骤 新建项目Bejs 新建文件package.json 新建文件Gruntfile.js 命令行执行grunt任务 一、新建项目Bejs源码放在src下,该目录有两个js文件,selector.js和ajax.js。编译后代码放在dest,这个grunt会...2014-06-07
  • 使用percona-toolkit操作MySQL的实用命令小结

    1.pt-archiver 功能介绍: 将mysql数据库中表的记录归档到另外一个表或者文件 用法介绍: pt-archiver [OPTION...] --source DSN --where WHERE 这个工具只是归档旧的数据,不会对线上数据的OLTP查询造成太大影响,你可以将...2015-11-24
  • 如何使用php脚本给html中引用的js和css路径打上版本号

    在搜索引擎中搜索关键字.htaccess 缓存,你可以搜索到很多关于设置网站文件缓存的教程,通过设置可以将css、js等不太经常更新的文件缓存在浏览器端,这样访客每次访问你的网站的时候,浏览器就可以从浏览器的缓存中获取css、...2015-11-24
  • 夜神android模拟器设置代理的方法

    夜神android模拟器如何设置代理呢?对于这个问题其实操作起来是非常的简单,下面小编来为各位详细介绍夜神android模拟器设置代理的方法,希望例子能够帮助到各位。 app...2016-09-20
  • android自定义动态设置Button样式【很常用】

    为了增强android应用的用户体验,我们可以在一些Button按钮上自定义动态的设置一些样式,比如交互时改变字体、颜色、背景图等。 今天来看一个通过重写Button来动态实...2016-09-20
  • jQuery 1.9使用$.support替代$.browser的使用方法

    jQuery 从 1.9 版开始,移除了 $.browser 和 $.browser.version , 取而代之的是 $.support 。 在更新的 2.0 版本中,将不再支持 IE 6/7/8。 以后,如果用户需要支持 IE 6/7/8,只能使用 jQuery 1.9。 如果要全面支持 IE,并混合...2014-05-31
  • Android WebView加载html5页面实例教程

    如果我们要在Android应用APP中加载html5页面,我们可以使用WebView,本文我们分享两个WebView加载html5页面实例应用。 实例一:WebView加载html5实现炫酷引导页面大多...2016-09-20
  • 安装和使用percona-toolkit来辅助操作MySQL的基本教程

    一、percona-toolkit简介 percona-toolkit是一组高级命令行工具的集合,用来执行各种通过手工执行非常复杂和麻烦的mysql和系统任务,这些任务包括: 检查master和slave数据的一致性 有效地对记录进行归档 查找重复的索...2015-11-24
  • C#注释的一些使用方法浅谈

    C#注释的一些使用方法浅谈,需要的朋友可以参考一下...2020-06-25
  • 深入理解Android中View和ViewGroup

    深入理解Android中View和ViewGroup从组成架构上看,似乎ViewGroup在View之上,View需要继承ViewGroup,但实际上不是这样的。View是基类,ViewGroup是它的子类。本教程我们深...2016-09-20
  • MySQL日志分析软件mysqlsla的安装和使用教程

    一、下载 mysqlsla [root@localhost tmp]# wget http://hackmysql.com/scripts/mysqlsla-2.03.tar.gz--19:45:45-- http://hackmysql.com/scripts/mysqlsla-2.03.tar.gzResolving hackmysql.com... 64.13.232.157Conn...2015-11-24
  • php语言中使用json的技巧及json的实现代码详解

    目前,JSON已经成为最流行的数据交换格式之一,各大网站的API几乎都支持它。我写过一篇《数据类型和JSON格式》,探讨它的设计思想。今天,我想总结一下PHP语言对它的支持,这是开发互联网应用程序(特别是编写API)必须了解的知识...2015-10-30
  • Android自定义WebView网络视频播放控件例子

    下面我们来看一篇关于Android自定义WebView网络视频播放控件开发例子,这个文章写得非常的不错下面给各位共享一下吧。 因为业务需要,以下代码均以Youtube网站在线视...2016-10-02