之所以涉及到这,是因为今天天气不错想着干点什么呢,同时在自己的App上添加一项新功能,第一项就是想添加一个可选择功能的dialog,在Android的App里发现咕咚App的运动类型选择的Dialog真的是漂亮,先上图:
下面就参考了这个界面做一下,思路是创建一个Activity让其Theme
android:launchMode="singleTask"
android:screenOrientation="portrait" <!-- 限制此页面数竖屏显示。!-->
android:theme="@style/load_dialog"
<style name="load_dialog" parent="@android:style/Theme.Dialog">
<item name="android:colorBackgroundCacheHint">@null</item>
<item name="android:windowFrame">@null</item> <!-- 边框 -->
<item name="android:windowIsFloating">true</item> <!-- 是否浮现在activity之上 -->
<item name="android:windowIsTranslucent">true</item> <!-- 半透明 -->
<item name="android:windowNoTitle">true</item> <!-- 无标题 -->
<!-- <item name="android:background">@drawable/dialog_type</item> dialog背景样式 -->
<item name="android:windowBackground">@android:color/transparent</item> <!-- 背景透明 -->
<item name="android:backgroundDimEnabled">false</item> <!-- 模糊 -->
</style>
这样就将Activity设置成功了,接下来就是设置显示的Xml文件,代码如下:
运动类型用 网格状的RadioGroup 完成。
首先为每个选项创建由Img和Text组合而成的、外形类似于RadioButton的组合View视图(下面简称URadioButton)
先看URadioButton的布局,上图标下文字:只需要把图片或文字填充到或中就可以实现内容不同的URadioButton
item_type_radiobutton.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_gravity="center"
android:gravity="center">
<com.ppl.get_loc.view.CircleImageView
android:id="@+id/civ_item_gd"
android:layout_width="50dip"
android:layout_height="50dip"
android:scaleType="centerCrop"
android:background="@android:color/transparent"
/>
<TextView
android:id="@+id/tv_item_gd"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"/>
</LinearLayout>
dialog 的XML文件的代码如下:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/dialog_type"
android:orientation="vertical" >
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/dialog_sport_type_title" >
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_marginTop="20dp"
android:gravity="center_horizontal"
android:text="选择运动类型"
android:textColor="@color/orange"
android:textSize="20sp" />
<ImageButton
android:id="@+id/ib_dialog_type_close"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginRight="5dp"
android:background="@android:color/transparent"
android:src="@drawable/v5_0_1_webview_stop_button" />
</RelativeLayout>
<GridView
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:id="@+id/gb_sport_type"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:horizontalSpacing="5dip"
android:numColumns="3"
android:stretchMode="columnWidth"
android:verticalSpacing="5dip" >
</GridView>
</LinearLayout>
为了使对话框边界呈现出弧形重写了背景,代码下:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
<solid android:color="#ffffff" />
<stroke
android:width="2dp"
android:color="#ff00ff00" />
<corners android:radius="15dp" />
<padding
android:bottom="2dp"
android:left="2dp"
android:right="2dp"
android:top="2dp" />
</shape>
为了使标题更漂亮,未标题写的背景代码如下:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
<gradient
android:angle="0"
android:centerColor="#93c1f2"
android:endColor="#000000"
android:startColor="#000000" />
<corners
android:topLeftRadius="15dp"
android:topRightRadius="15dp"
/>
</shape>
至此完成了对话框的页面布局,现在只差为GridView写适配器,其中注意俩点,
一:记住选择运动类型,所以需要把每次选中的运动类型进行保存,保存方法类似保存登陆用户信息的方法,每次进入软件时读取之前保存的运动方式,确定主页运动方式的标签。
二:标签更新,意思是选中的运动方式与其他运动图片的区别,我采用的是,当点击运动时,对点击的该运动与前一运动状态的更新,完成连续点击能及时更新,代码如下所示:
package com.ppl.get_loc.ui;
import java.util.ArrayList;
import java.util.HashMap;
import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.GridView;
import android.widget.ImageButton;
import com.ppl.get_loc.R;
import com.ppl.get_loc.utils.PublicData;
public class ActivitySportType extends Activity {
private ImageButton ib_dialog_type_close;
private GridView gb_sport_type;
private int[] img_res = {R.drawable.bike,R.drawable.jogging,R.drawable.mountaineer,R.drawable.caneeing,
R.drawable.swimmingpng,R.drawable.windurfing};
private String[] sport_type = {"骑行","跑步","爬山","划船","游泳","帆船"};
private ArrayList<HashMap<String, Object>>data;
private Context mContext;
private SharedPreferences sharedPreferences;
//对数据进行编辑
private SharedPreferences.Editor editor;
private GVSportAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
setContentView(R.layout.activity_activity_sport_type);
super.onCreate(savedInstanceState);
initView();
initData();
}
private void initView() {
// TODO Auto-generated method stub
ib_dialog_type_close = (ImageButton)findViewById(R.id.ib_dialog_type_close);
gb_sport_type = (GridView)findViewById(R.id.gb_sport_type);
mContext = getApplicationContext();
sharedPreferences = mContext.getSharedPreferences(PublicData.sportTypeFile, Context.MODE_PRIVATE);
editor = sharedPreferences.edit();
}
private void initData() {
// TODO Auto-generated method stub
ib_dialog_type_close.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
}
});
data = new ArrayList<HashMap<String,Object>>();
for(int i=0;i<sport_type.length;i++){
if(i == PublicData.sportType){
HashMap<String, Object> map = new HashMap<String, Object>();
map.put("text", sport_type[i]);
map.put("img", PublicData.img_res_ligt[i]);
data.add(map);
}else{
HashMap<String, Object> map = new HashMap<String, Object>();
map.put("text", sport_type[i]);
map.put("img", img_res[i]);
data.add(map);
}
}
adapter = new GVSportAdapter(mContext, data);
gb_sport_type.setAdapter(adapter);
gb_sport_type.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
//对数据进行读取
PublicData.sportType = sharedPreferences.getInt(PublicData.keySportType, 0);
HashMap<String, Object> map_to_gray = (HashMap<String, Object>)data.get(PublicData.sportType);
map_to_gray.put("img", img_res[PublicData.sportType]);
HashMap<String, Object> map_ligt = (HashMap<String, Object>)data.get(arg2);
map_ligt.put("img",PublicData.img_res_ligt[arg2]);
editor.putInt(PublicData.keySportType, arg2);
editor.commit();
adapter.notifyDataSetChanged();
}
});
}
}
效果如下图所示:
接下来就是,当选中运动类型后,数据交互。
通过两部完成数据交互:
1.启动dialog时,用的是:startActivityForResult;
private void selectSportType() {
// TODO Auto-generated method stub
Intent intent = new Intent();
intent.setClass(getActivity(), ActivitySportType.class);
startActivityForResult(intent, SELECT_TYPE);
}
2.调用finish前调用setResult,向调用Activity返回一个结果。
哎呦,新发现:因为这个Activity的主题设置为dialog,发现执行顺序是 startActivityForResult 后直接执行 onActivityResult 然后才启动以dialog为主题的Activity,当Activity执行结束setResult后finish后不执行onActivityResult 。新鲜喽。
饿了,阴天了,可能会下雨了,而且没网了,所以下班了,明天继续。
查资料得到这样的方法:
方法如下:
假设:主Activity为MainActivity;被调用的Dialog类为SampleDialog
此时我们需定义一个接口类:
interface MyListener{
public void refreshActivity(String text);
}
在SampleDIalog的构造函数中传入MyListener:
public MyListener (MyListener myListener){
this.mMyListener = myListener;
}
并且在需要返回的地方调用refreshActivity()方法:
mMyListener.refreshActivity();
然后在MainActivity中实现MyListener接口,并在show Dialog时传入实现的myListener:
private MyListener myListener = new MyListener(){
@Override
public void refreshActivity(String text){
this.mTextView1.setText(text);
}
}
};new SampleDialog(myListener).show;
这样便能从Dialog返回需要的数据。
我采用的是将选择的运动方式保存成全局的变量,在finish掉以Dialog为主题的activity后返回原activity时,在OnResume中刷新。完成!