代码改变世界

是ActivityGroup 的BUG?是对机制理解不深刻?还是逻辑错误?还是。。。不知道了?

2010-09-27 10:32  Terry_龙  阅读(2777)  评论(8编辑  收藏  举报

首先,先喷一下张艺谋的片子,你他妈太黑了~!什么史上最干净的爱情片,我说是史上最烂的爱情片,只能把无知当纯情。拍电影拍得一点诚意都没有,只会抄韩国的爱情片,记得有一部韩国片跟你这部剧情都差不多~!你就使劲抄吧~!!浪费我160大洋,进去睡觉。

 

喷到这里。

首先,跟园主说一声,不好意思,此篇文章应该发布到博问区,不过我想就此问题跟大家多勾通一下,如果违规了,请撤下首页。

这一两天碰到一个问题,是一个关于ActivityGroup 的问题,因为项目需要,必须把一个自定义的PreferenceActivity 的界面嵌套在ActivityGroup 里面,可是当我嵌套在里面的时候发现了一个问题。就是PreferenceActivity 的元素不会自动更新UI,这是比较致命的,不知道为什么会出现这个问题。

查了很久,首先我怀疑是我的自定义preference写的有问题,改了一遍,然后再运行还是一样。

单独运行该 preferenceActivity 试了一下,界面可以按照自己的需求更新UI,那就是说不是我这个自定义的preference 的逻辑问题?这点还不敢确定。

那么我怀疑是 ActivityGroup 不允许底下Activity 元素的UI自动更新,那么新建一个普通的Activity 来试试,在这普通的Activity 里面只有一个按钮同样是点击之后弹出对话框然后改变按钮的字,试了一下,。更新成功。。。耶?那么说ActivityGroup 还是允许底下Activity UI 元素更新的?那么问题出在哪呢?

我又再调试跟踪了代码,确定有执行settext的代码?那是不是说preferenceActivity 和ActivityGroup有冲突?不知道所然,下面贴出我碰到问题的全部代码,由于在公司有加密软件无法将DEMO提供给大家,大家可以根据代码新建一个工程,一起来研究这个问题。

 

自定义的PreferenceScreenExt 源码:

 

 

package asai.cn.seekbardemo;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.content.res.TypedArray;
import android.os.Parcel;
import android.os.Parcelable;
import android.preference.Preference;
import android.preference.PreferenceGroup;
import android.preference.Preference.BaseSavedState;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.SimpleAdapter;
import android.widget.TextView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.TextView.SavedState;

public class PreferenceScreenExt extends PreferenceGroup implements
        OnItemClickListener, DialogInterface.OnDismissListener {

    
private Dialog dialog;
    
private TextView title, summary;
    
private RelativeLayout area;
    
private ListView listView;
    List
<Preference> list;

    
private List<HashMap<String, String>> listStr;
    
private CharSequence[] mEntries;
    
private String mValue;

    
private SimpleAdapter simple;

    
public PreferenceScreenExt(Context context, AttributeSet attrs) {
        
this(context, attrs, android.R.attr.preferenceScreenStyle);
        
// TODO Auto-generated constructor stub
    }

    
public PreferenceScreenExt(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, android.R.attr.preferenceScreenStyle);
        
// TODO Auto-generated constructor stub
        int resouceId = attrs.getAttributeResourceValue(null"Entries"0);
        
if (resouceId > 0) {
            mEntries 
= getContext().getResources().getTextArray(resouceId);
        }
    }

    @Override
    
protected View onCreateView(ViewGroup parent) {
        
// TODO Auto-generated method stu
        View view = LayoutInflater.from(getContext()).inflate(
                R.layout.preference_screen, 
null);
        area 
= (RelativeLayout) view.findViewById(R.id.area);

        title 
= (TextView) view.findViewById(R.id.title);
        summary 
= (TextView) view.findViewById(R.id.summary);
        title.setText(getTitle());
        summary.setText(getPersistedString(getSummary().toString()));
        area.setOnClickListener(
new OnClickListener() {

            @Override
            
public void onClick(View v) {
                
// TODO Auto-generated method stub
                showDialog();
            }
        });
        
return view;
    }

    
public void bindView(ListView listview) {
        
int length = mEntries.length;
        
int i = 0;
        listStr 
= new ArrayList<HashMap<String, String>>();
        
for (i = 0; i < length; i++) {
            HashMap
<String, String> map = new HashMap<String, String>();
            map.put(
"keyname", mEntries[i].toString());
            listStr.add(map);
        }
        simple 
= new SimpleAdapter(getContext(), listStr, R.layout.dialog_view,
                
new String[] { "keyname" }, new int[] { R.id.text });
        listview.setAdapter(simple);
        listview.setOnItemClickListener(
this);
    }

    
public void showDialog() {
        listView 
= new ListView(getContext());
        bindView(listView);
        dialog 
= new Dialog(getContext(), android.R.style.Theme_NoTitleBar);
        dialog.setContentView(listView);
        dialog.setOnDismissListener(
this);
        dialog.show();
    }

    @Override
    
public void onItemClick(AdapterView<?> parent, View view, int position,
            
long id) {
        
// TODO Auto-generated method stub
        mValue = listStr.get(position).get("keyname").toString();
        persistString(mValue);
        callChangeListener(mValue);
        PreferenceScreenExt.
this
                .setOnPreferenceChangeListener(
new OnPreferenceChangeListener() {

                    @Override
                    
public boolean onPreferenceChange(Preference preference,
                            Object newValue) {
                        
// TODO Auto-generated method stub
                        if (temp != null) {
                            temp.onPreferenceChange(PreferenceScreenExt.
this,
                                    newValue);
                        }
                        
return true;
                    }
                });
        dialog.dismiss();
    }

    @Override
    
public void onDismiss(DialogInterface dialog) {
        
// TODO Auto-generated method stub
    }

    
private OnPreferenceChangeListener temp;

    
public interface OnPreferenceChangeListener {
        
public boolean onPreferenceChange(Preference preference, Object newValue);
    }

    
public void setOnPreferenceChangeListener(
            OnPreferenceChangeListener preference) {
        
this.temp = preference;
    }

    
public void setValue(String value) {
        summary.setText(value);
        persistString(value);
        summary.invalidate();
    }

}

 

 

对应的XML布局文件:

 

dialog_view.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout android:layout_width="fill_parent"
    xmlns:android
="http://schemas.android.com/apk/res/android"
    android:orientation
="vertical" android:gravity="center"
    android:layout_height
="fill_parent" >


    
<TextView android:id="@+id/text" android:layout_marginLeft="20dp"
        android:textAppearance
="?android:attr/textAppearanceLarge"
        android:textSize
="35sp" android:layout_width="wrap_content"
        android:layout_height
="wrap_content">
    
</TextView>


</LinearLayout> 

 

 

 

preference_screen.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout android:id="@+id/area" android:gravity="center_vertical"
    android:layout_marginTop
="5px" android:clickable="true"
    xmlns:android
="http://schemas.android.com/apk/res/android"
     android:layout_width
="fill_parent"
    android:layout_height
="wrap_content">

    
<TextView android:id="@+id/title" android:layout_marginLeft="20dp"
        android:textAppearance
="?android:attr/textAppearanceLarge"
        android:textSize
="35sp" android:layout_width="wrap_content"
        android:layout_height
="wrap_content">
    
</TextView>
    
<TextView android:id="@+id/summary"
        android:layout_marginRight
="20dp" android:textSize="35sp"
        android:textAppearance
="?android:attr/textAppearanceLarge"
        android:layout_alignParentRight
="true" android:layout_width="wrap_content"
        android:layout_height
="wrap_content">
    
</TextView>
</RelativeLayout>

 

 

XML文件夹下的XML文件:

 

preference.xml
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">

    
<asai.cn.seekbardemo.PreferenceScreenExt
        
Entries="@array/country" android:title="收音区域" android:summary="美国"
        android:persistent
="true" android:key="eeg">
    
</asai.cn.seekbardemo.PreferenceScreenExt>
</PreferenceScreen>

 

 

main.java 对应代码

 

package asai.cn.seekbardemo;

import android.app.ActivityGroup;
import android.app.LocalActivityManager;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.Window;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.LinearLayout;

public class main extends ActivityGroup implements OnClickListener {

    
private LocalActivityManager lm;
    
private LinearLayout layout;
    
private Button btn, btn2;

    @Override
    
protected void onCreate(Bundle savedInstanceState) {
        
// TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.group);

        lm 
= getLocalActivityManager();
        btn 
= (Button) findViewById(R.id.Button01);
        btn2 
= (Button) findViewById(R.id.Button02);

        btn.setOnClickListener(
this);
        btn2.setOnClickListener(
this);
        layout 
= (LinearLayout) findViewById(R.id.layout);
        Intent intent 
= new Intent(this, seekBarDemo.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        Window w 
= lm.startActivity("test", intent);
        View v 
= w.getDecorView();
        layout.removeAllViews();
        layout.addView(v);
    }

    @Override
    
public void onClick(View v) {
        
// TODO Auto-generated method stub
        switch (v.getId()) {
        
case R.id.Button01:
            Intent intent 
= new Intent(this, seekBarDemo.class);
            intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
            Window w 
= lm.startActivity("test", intent);
            View view 
= w.getDecorView();
            layout.removeAllViews();
            layout.addView(view);
            
break;
        
case R.id.Button02:
            Intent 
in = new Intent(this, test.class);
            
in.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
            Window win 
= lm.startActivity("ww"in);
            View vw 
= win.getDecorView();
            layout.removeAllViews();
            layout.addView(vw);
            
break;
        
default:
            
break;
        }
    }
}

 

 

对应的XML布局文件:

 

group.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout android:orientation="vertical"
    android:layout_width
="fill_parent" android:layout_height="fill_parent"
    xmlns:android
="http://schemas.android.com/apk/res/android">

    
<LinearLayout android:layout_width="fill_parent"
        android:gravity
="center_horizontal" android:layout_height="wrap_content">
        
<Button android:text="preference界面" android:id="@+id/Button01"
            android:layout_width
="wrap_content" android:layout_height="wrap_content"></Button>
        
<Button android:text="普通" android:id="@+id/Button02"
            android:layout_width
="wrap_content" android:layout_height="wrap_content"></Button>
    
</LinearLayout>
    
<LinearLayout android:id="@+id/layout"
        android:layout_width
="fill_parent" android:layout_height="wrap_content"></LinearLayout>
</LinearLayout>    

 

 

 

PreferenceActivity 界面代码 SeekBarDemo.java:

 

package asai.cn.seekbardemo;

import android.os.Bundle;
import android.preference.Preference;
import android.preference.PreferenceActivity;
import android.preference.Preference.OnPreferenceChangeListener;
import android.widget.TextView;

public class seekBarDemo extends PreferenceActivity {
    
private Preference eeg;

    
/** Called when the activity is first created. */
    @Override
    
public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.xml.preference);

        final PreferenceScreenExt pre 
= (PreferenceScreenExt) findPreference("eeg");
        pre.setOnPreferenceChangeListener(
new OnPreferenceChangeListener() {

            @Override
            
public boolean onPreferenceChange(Preference preference,
                    Object newValue) {
                
// TODO Auto-generated method stub
                pre.setValue(String.valueOf(newValue));
                
return true;
            }
        });
    }

}

 

 

普通的Activity 界面代码test.java:

 

package asai.cn.seekbardemo;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class test extends Activity {
    @Override
    
protected void onCreate(Bundle savedInstanceState) {
        
// TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.test);

        final Button btn 
= (Button) findViewById(R.id.Button01);
        btn.setOnClickListener(
new OnClickListener() {

            @Override
            
public void onClick(View v) {
                
// TODO Auto-generated method stub
                new AlertDialog.Builder(test.this).setMessage("修改").setTitle(
                        
"提示").setPositiveButton(android.R.string.ok,
                        
new DialogInterface.OnClickListener() {

                            @Override
                            
public void onClick(DialogInterface dialog,
                                    
int which) {
                                
// TODO Auto-generated method stub
                                btn.setText("修改后的按钮");
                            }
                        }).show();
            }
        });
    }
}

 

 

配置文件:

 

AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package
="asai.cn.seekbardemo" android:versionCode="1"
    android:versionName
="1.0">
    
<application android:icon="@drawable/icon" android:label="@string/app_name">
        
<activity android:name=".main" android:label="@string/app_name">
            
<intent-filter>
                
<action android:name="android.intent.action.MAIN" />
                
<category android:name="android.intent.category.LAUNCHER" />
            
</intent-filter>
        
</activity>
        
<activity android:name=".test" android:label="@string/app_name">
            
<intent-filter>

                
<category android:name="android.intent.category.LAUNCHER" />
            
</intent-filter>
        
</activity>
        
<activity android:name=".seekBarDemo" android:label="@string/app_name">
            
<intent-filter>
             
                
<category android:name="android.intent.category.LAUNCHER" />
            
</intent-filter>
        
</activity>

    
</application>
    
<uses-sdk android:minSdkVersion="7" />

</manifest> 

 

 

希望就此问题和大家探讨一下。