«

[安卓]手机管家(三)homeActivity

时间:2024-3-2 18:20     作者:韩俊     分类: Android


跳转后的homeActivity,要在背景上再显示功能图标,这又是一个view,而这个需要adapter去实现,详情看日志day5.15的介绍

homeactivity

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
 <TextView
      android:layout_width="fill_parent"
      android:layout_height="60dp"
      android:text="功能列表"
      android:background="#00FF00"
      android:gravity="center"
      android:textSize="25sp"/>   
  <GridView
       android:id="@+id/gv_home_nine"
       android:layout_width="fill_parent"
       android:layout_height="wrap_content"
       android:gravity="center"
       android:numColumns="3"/>
</LinearLayout>

item_home
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/iv_home_pic"
        android:src="@drawable/ic_launcher"
        android:layout_gravity="center"
        android:layout_margin="10dp"/>
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/tv_home_name"
        android:layout_gravity="center_horizontal"
        android:text="功能"/>
</LinearLayout>

activity,注意最后一个重载方法,用来显示view的
public class HomeActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_home);
        GridView gv_home_nine = (GridView) findViewById(R.id.gv_home_nine); 

        gv_home_nine.setAdapter(new MyListAdapter());
    }
    class MyListAdapter extends BaseAdapter{

        @Override
        public int getCount() {
            // TODO Auto-generated method stub
            return 9;
        }

        @Override
        public Object getItem(int position) {
            // TODO Auto-generated method stub
            return null;
        }

        @Override
        public long getItemId(int position) {
            // TODO Auto-generated method stub
            return 0;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            // TODO Auto-generated method stub
                View view = View.inflate(HomeActivity.this, R.layout.item_home, null);
            return view;
        }

    }
}


导入准备好的图片后,需要显示他们





希望能实现一个跑马灯效果,显示一些额外的信息,在activity_home里加上一个textView,这里用系统的控件不好实现,无法获得焦点,为了能够自动获得焦点,一进入这个activity就能显示出来,这就需要自定义控件,FocusTextView继承于textView,他要实现3个构造方法,最后调用一个方法来判断是否有焦点

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

public class FocusTextView extends TextView {

    public FocusTextView(Context context) {
        super(context);
        // TODO Auto-generated constructor stub
    }
    public FocusTextView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        // TODO Auto-generated constructor stub
    }
    public FocusTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        // TODO Auto-generated constructor stub
    }
    //判断是否获得焦点
    @Override
    public boolean isFocused() {
        // 返回true确保获得焦点
        return  true;
    }
}

在layout里使用全面来调用
<com.rjl.mobilephonemanager.FocusTextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="您当前使用的是手机卫士2.0版本,当前最新版本是3.0版本,建议下载!"
        android:singleLine="true"
        android:textSize="14sp"
        android:ellipsize="marquee"
        android:focusable="true"
        android:clickable="true" />



OK,现在来实现具体功能块,首先完善之前的splash的更新功能,在设置里应该有一个是否自动更新的功能,单独需要一个settingActivity,首先记得manifest里声明下

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    <TextView 
        android:layout_width="fill_parent"
        android:layout_height="60dp"
        android:text="设置中心"
        android:background="#00FF00"
        android:gravity="center"
        android:textSize="25sp" />
     <RelativeLayout
          android:layout_width="fill_parent"
          android:layout_height="wrap_content">
        <TextView
          android:id="@+id/tv_setting_title"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:text="自动更新"
          android:layout_margin="5dp"
          android:textSize="20sp"/>
        <TextView
          android:id="@+id/tv_setting_description"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:text="自动更新开启"
          android:textSize="16sp"
          android:layout_marginLeft="5dp"
          android:layout_below="@+id/tv_setting_title"/>
        <CheckBox
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:layout_alignParentRight="true"
          android:layout_centerVertical="true"/>
        </RelativeLayout>
</LinearLayout>


实现点击的跳转,需要在homeactivity里实现MyOnItemClickListener

protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_home);
        GridView gv_home_nine = (GridView) findViewById(R.id.gv_home_nine); 

        gv_home_nine.setAdapter(new MyListAdapter());
        gv_home_nine.setOnItemClickListener(new MyOnItemClickListener());
    }
    class MyOnItemClickListener implements OnItemClickListener{
        //注意position的值,在数组里是最后一个,8
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position,
                long id) {
            // TODO Auto-generated method stub
            switch (position) {
            case 8:
                //跳入到setting页面
                Intent intent = new Intent(HomeActivity.this,SettingActivity.class);
                startActivity(intent);

                break;

             default:
                break;
            }
        }

    }

此时再回过头想想,setting里会有多个打钩确认,如果都是这么写就繁琐了,所以可以抽出来,通过自定义组合控件来实现,settingItem,继承于relativeLayout,同样有3个构造方法

前面有一个自定义控件了,应该建一个专用的包存这一类控件


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

public class SettingItem extends RelativeLayout {

    public SettingItem(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        // TODO Auto-generated constructor stub
    }

    public SettingItem(Context context, AttributeSet attrs) {
        super(context, attrs);
        // TODO Auto-generated constructor stub
    }

    public SettingItem(Context context) {
        super(context);
        // TODO Auto-generated constructor stub
    }

}

在这三个方法里都应该初始化,需要一个方法init()

public class SettingItem extends RelativeLayout {

    public SettingItem(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        // TODO Auto-generated constructor stub
        init();
    }
    public SettingItem(Context context, AttributeSet attrs) {
        super(context, attrs);
        // TODO Auto-generated constructor stub
        init();
    }
    public SettingItem(Context context) {
        super(context);
        // TODO Auto-generated constructor stub
        init();
    }
    //初始化,三个构造函数都需要调用它
    //通过这个初始化,通过填充器将三个控件填充到这个view,再将view加入到组合控件里
    //在activity_setting里组合,另需一个setting_item来实现原来的三个控件
    private void init() {
        // TODO Auto-generated method stub
        View view=  View.inflate(getContext(), R.layout.setting_item, null);    
        //将控件的view加载到这个view上
        this.addView(view);
    }
}

原来的layout里就只需要一个组合控件,但是还是要一个layout去实现组合控件里的三个控件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    <TextView 
        android:layout_width="fill_parent"
        android:layout_height="60dp"
        android:text="设置中心"
        android:background="#00FF00"
        android:gravity="center"
        android:textSize="25sp" />
    <com.rjl.mobilephonemanager.ui.SettingItem
          android:layout_width="fill_parent"
          android:layout_height="wrap_content"/>
</LinearLayout>

新建一个layout setting_item,原有的三个控件弄进来
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" >
        <TextView 
            android:id="@+id/tv_setting_title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"  
            android:text="自动更新"    
            android:layout_margin="5dp"            
            android:textSize="20sp"/>
        <TextView 
            android:id="@+id/tv_setting_description"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="自动更新开启"
            android:textSize="16sp"
            android:layout_marginLeft="5dp"
            android:layout_below="@id/tv_setting_title"/>
        <CheckBox            
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_alignParentRight="true"
             android:layout_centerVertical="true"/>
</RelativeLayout>

这中间有一个问题困扰了好久,UNbound prefix,老师在的完整代码里有一个额外的前缀,后续要用到,但是目前没有,我一股脑复制进来,导致XML解析错误,更进步导致无法通过R.layout找到view,去掉那一段就好了




组合控件还有另一个实现方式,注意init(0的第三个参数,ViewGroup型的root或者是parent,因为这个组合控件的view实际上是挂在RelativeLayout上,所以第三个参数传递一个this指向他,就相当于第一种方式的addView了

至此自定义组合控件解决了,接下来实现功能,勾选上就能自动更新

点击事件,给activity_setting里的组合控件加一个ID,oncreate里调用,他是一个自定义的settingItem类





点击需要listener

settingItem = (SettingItem) findViewById(R.id.settingitem_autoupdate); 
        settingItem.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub

            }        
         });

在onclick这个callback里需要实现在整个checkbox点击都有效果,要ID


点击后面的小框框没有作用,除了框框意外的地方点击后能实现开启、关闭的字样切换

@Override
            public void onClick(View v) {
                // 注意通过view v来找到ID
                CheckBox cb = (CheckBox) v.findViewById(R.id.cb_settingitem);
                TextView tv_setting_description = (TextView) v.findViewById(R.id.tv_setting_description);

                if(cb.isChecked()){
                    //勾上点击后要置成false
                    cb.setChecked(false);
                    tv_setting_description.setText("自动更新关闭");
                }else{
                    cb.setChecked(true);
                    tv_setting_description.setText("自动更新开启");
                }

            }        
         });

现在要保存用户对此项的设置,SharedPreferences,另外,由于之前一进去就是写死的显示是开启,我们应该根据保存状态来显示是开启还是关闭,所以这个通过ID来获取view应该拉出来通过settingitem获取,而不是在onclick里用v来获取控件在layout里写入的。这一部分的逻辑有点乱
public class SettingActivity extends Activity {
    private CheckBox cb;
    private TextView tv_setting_description;
    @Override
    protected void onCreate(Bundle savedInstanceState) {

        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_setting);  
        final SharedPreferences  sp = getSharedPreferences("config", MODE_PRIVATE);
        SettingItem settingItem = (SettingItem) findViewById(R.id.settingitem_autoupdate);  

        cb = (CheckBox) settingItem.findViewById(R.id.cb_settingitem);
        tv_setting_description = (TextView) settingItem.findViewById(R.id.tv_setting_description);
        //默认是true
        boolean ischeck=  sp.getBoolean("autoupdate", true);
        cb.setChecked(ischeck);
        if (ischeck) {
            tv_setting_description.setText("自定更新开启");   
        }
        else {
            tv_setting_description.setText("自定更新关闭");           
        }
        settingItem.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {

                Editor editor = sp.edit();
                if(cb.isChecked()){
                    //勾上点击后要置成false
                    cb.setChecked(false);
                    tv_setting_description.setText("自动更新关闭");             
                    editor.putBoolean("autoupdate", false);           
                }else{
                    cb.setChecked(true);
                    tv_setting_description.setText("自动更新开启");             
                    editor.putBoolean("autoupdate", true);                    
                }
                editor.commit();
            }        
         });
    }
}

OK,现在要判断用户是否设置了自动更新再决定是否下载,回到splashActivity调用SharedPreferences



能这样直接调用enterHome()吗?如果用户没有设置自动更新,这样不就永远不会更新了?

如果用户没有设置自动更新,则应该是提示用户是否更新,需要给一个超时时间,而不是直接enterHome(),不能直接在主线程中等待,而是需要子线程,主线程只是刷UI滴哟


@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_splash);
        TextView tv_splash_version = (TextView) findViewById(R.id.tv_splash_version);
        //上面的声明要注意是空字符串,而不是null
        tv_splash_version.setText("版本: "+getVersion());
        //解析下载进度
        tv_splash_downloadprogress = (TextView) findViewById(R.id.tv_splash_downloadprogress);
        //需要判断用户的设置,如果用户设置了自动更新,则就打开,else 直接进入主界面
        SharedPreferences sp =getSharedPreferences("config", MODE_PRIVATE);
        if(sp.getBoolean("autoupdate", true)){
           Update();
        }else{
            //如果用户没有设置自动更新,则应该是提示用户是否更新,需要给一个超时时间,而不是直接enterHome()
            //不能直接在主线程中等待,而是需要子线程
             new Thread(new Runnable() {
                @Override
                public void run() {
                    // TODO Auto-generated method stub
                    try {
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }   
                    //主线程睡后,由这个将enterHome交给主线程,相当于给主线程发了消息
                    runOnUiThread(new   Runnable() {
                        public void run() {
                            enterHome();
                        }
                    });
                }
              }).start(); 
        }
    }



标签: android

热门推荐