如果你想自定义一个对话框,你可以使用布局元素来创造你的对话框的布局。定义好布局后,将根View对象或者布局资源ID传给setContentView(View).
例如,创建如图所示的对话框:
创建一个xml布局custom_dialog.xml:
view plain
http://schemas.android.com/apk/res/android"
android:id="@+id/layout_root"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="10dp"
>
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_marginRight="10dp"
/>
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:textColor="#FFF"
/>
该xml定义了一个LinearLayout中的一个ImageView 和一个TextView。
将以上布局设为对话框的content view,并且定义ImageView 和 TextView的内容:
view plain
Context mContext = getApplicationContext();
Dialog dialog = new Dialog(mContext);
dialog.setContentView(R.layout.custom_dialog);
dialog.setTitle("Custom Dialog");
TextView text = (TextView) dialog.findViewById(R.id.text);
text.setText("Hello, this is a custom dialog!");
ImageView image = (ImageView) dialog.findViewById(R.id.image);
image.setImageResource(R.drawable.android);
在初始化Dialog之后,使用setContentView(int),将布局资源id传给它。现在Dialog有一个定义好的布局,你可以使用findViewById(int)来找到该元素的id并修改它的内容。
使用前面所讲的方法显示对话框。
一个使用Dialog类建立的对话框必须有一个标题。如果你不调用setTitle(),那么标题区域会保留空白。如果你不希望有一个标题,那么你应该使用AlertDialog类来创建自定义对话框。然而,由于一个AlertDialog使用AlertDialog.Builder类来建立最方便,所以你没有方法使用setContentView(int),而是只能使用setView(View)。该方法接受一个View对象,所以你需要从xml中展开你的根View。
要展开一个xml布局,使用 getLayoutInflater() (或 getSystemService())取得LayoutInflater,然后调用inflate(int, ViewGroup),第一个参数为布局id,而第二个参数为根view的id。现在,你可以使用展开后的布局来找到View对象并定义ImageView和TextView元素的内容。然后实例化AlertDialog.Builder并使用setView(View)来为对话框设置展开后的布局。例如:
view plain
AlertDialog.Builder builder;
AlertDialog alertDialog;
Context mContext = getApplicationContext();
LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(LAYOUT_INFLATER_SERVICE);
View layout = inflater.inflate(R.layout.custom_dialog,
(ViewGroup) findViewById(R.id.layout_root));
TextView text = (TextView) layout.findViewById(R.id.text);
text.setText("Hello, this is a custom dialog!");
ImageView image = (ImageView) layout.findViewById(R.id.image);
image.setImageResource(R.drawable.android);
builder = new AlertDialog.Builder(mContext);
builder.setView(layout);
alertDialog = builder.create();
使用AlertDialog来自定义对话框,可以利用其内置特性例如按钮、选择列表、标题、图标等。
本文主要介绍如何使用类似新浪微博客户端下拉刷新效果的ListView,关于其实现原理见下拉刷新ListView的实现原理。
首先让我们看下效果
四张图分别为第一次下拉、第一次释放、第一次刷新中、第二次下拉的效果,其中的文本可以设置,可以下载Demo代码DropDownToRefreshListView编译运行。下面看如何使用
1、引入公共库
引入TrineaAndroidCommon GoogleCode或(TrineaAndroidCommon Git)作为android项目的library,或是自己抽取其中的DropDownToRefreshListView部分使用
2、在xml中配置
用现在的DropDownToRefreshListView替换原来的ListView即可
<com.trinea.common.view.DropDownToRefreshListView android:id="@+id/statusListView" android:layout_width="match_parent" android:layout_height="match_parent"/>
3、在java类中调用
主要是设置listView的refresh listener
DropDownToRefreshListView statusListView = (DropDownToRefreshListView)findViewById(R.id.statusListView); statusListView.setOnRefreshListener(new OnRefreshListener() { @Override public void onRefresh() { doSomeThing(); statusListView.onRefreshComplete("更新成功"); } });
注意:
1、刷新结束时需手动调用listView的onRefreshComplete函数
上面的onRefresh中最后调用了listView的onRefreshComplete函数,这个函数会对listView进行一些重置
如果onRefresh里面为线程操作,需要在线程完成后调用onRefreshComplete函数,如Thread的run函数结束前,AsyncTask子类的onPostExecute函数中。
2、刷新Header占用了ListView position为0的位置
通过本文第二大部分对原理的介绍可以知道,DropDownToRefreshListView的实现是通过在原来的ListView添加了个Header,所以刷新Header占用了position为0的位置,对于listView中的其他item都是从position从1开始算起。使用statusListView.setSelection(0)会滚动到的刷新View的item,使用statusListView.setSecondPositionVisible()设置position为1(即第二个)的item可见。
4、其他设置
4.1 设置相关的提示文本,在strings.xml文件中重定义相关变量,如
<string name="drop_down_to_refresh_list_pull_tips">下拉可以刷新...</string> <string name="drop_down_to_refresh_list_release_tips">松开可以刷新...</string> <string name="drop_down_to_refresh_list_refreshing_tips">刷新中...</string> <string name="drop_down_to_refresh_list_refresh_view_tips">点击可以刷新...</string>
4.2 设置相关文本的颜色
在colors.xml文件中重定义dropDownToRefreshListHeaderFontColor变量,如
<color name="drop_down_to_refresh_list_header_font_color">#424952</color>
4.3 设置刷新结束时listView刷新View对上次更新的提示
可以使用onRefreshComplete(CharSequence lastUpdatedText)或单独调用onRefreshComplete(CharSequence lastUpdatedText)
4.4 设置刷新View为开始刷新时状态
需要时也可以手动调用onRefreshBegin表示开始刷新,这个函数只会设置相关View的状态,不会进行真正的刷新操作(onRefresh函数完成),同onRefreshComplete效果相反。
本文主要介绍如何实现类似新浪微博客户端下拉刷新效果的ListView。关于其使用见下拉刷新ListView的使用。
首先让我们看下效果
四张图分别为第一次下拉、第一次释放、第一次刷新中、第二次下拉的效果,其中的文本可以设置,可以下载Demo代码DropDownToRefreshListView编译运行。下面看如何使用实现
1、源代码
见DropDownToRefreshListView.java,其中注释明确。
项目地址见TrineaAndroidCommon GoogleCode或(TrineaAndroidCommon Git)
2、原理
通过对ListView添加了一个刷新layout(源代码res/layout/drop_down_to_refresh_list_header.xml)作为header,在滚动中时不断改变header的高度和内容并记录一些状态,在用户手指离开屏幕时根据状态决定进行刷新还是放弃刷新。
主要是通过重写ListView的onTouchEvent和OnScrollListener的onScrollStateChanged、onScroll函数实现
先介绍下刷新状态共有四种,如下:
CLICK_TO_REFRESH 点击刷新状态,为初始状态
DROP_DOWN_TO_REFRESH 当刷新layout高度低于一定范围时,为此状态
RELEASE_TO_REFRESH 当刷新layout高度高于一定范围时,为此状态
REFRESHING 刷新中时,为此状态
2.1 onTouchEvent函数
public boolean onTouchEvent(MotionEvent event)根据用户在屏幕上的move事件,进行相应操作,如下:
ACTION_DOWN表示用户手指刚接触屏幕,会记录用户此时touch的点的y坐标,在下面调整高度时使用
ACTION_MOVE表示用户手指正在屏幕上移动,此时会不断调整header的高度,即下拉时刷新item部分高度的不断变化
ACTION_UP表示用户手指离开屏幕,此时会根据当前状态决定是进行刷新还是放弃刷新,若刷新调用用户设置的OnRefreshListener接口。
2.2 onScrollStateChanged函数
public void onScrollStateChanged(AbsListView view, int scrollState)
记录listView当前的滚动状态到currentScrollState,包括三种状态:
SCROLL_STATE_TOUCH_SCROLL ListView正在滚动中,并且手指尚未离开屏幕
SCROLL_STATE_FLING ListView仍在滚动中,但用户手指已经离开屏幕
SCROLL_STATE_IDLE ListView已经停止滚动
2.3 onScroll函数
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount)
根据listView当前的滚动状态即currentScrollState和当前刷新的状态不断修改header内容显示和刷新状态,如下:
ListView为SCROLL_STATE_TOUCH_SCROLL状态(按着不放滚动中)并且刷新状态不为REFRESHING
a. 刷新对应的item可见时,若刷新layout高度超出范围,则置刷新状态为RELEASE_TO_REFRESH;若刷新layout高度低于高度范围,则置刷新状态为DROP_DOWN_TO_REFRESH。
b. 刷新对应的item不可见,重置header
ListView为SCROLL_STATE_FLING状态(松手滚动中)
a. 若刷新对应的item可见并且刷新状态不为REFRESHING,设置position为1的(即第二个)item可见
b. 若反弹回来,设置position为1的(即第二个)item可见
参考:http://johannilsson.com/2011/03/13/android-pull-to-refresh-update.html