Android第一个项目 SuperProfile 记录(更新中)

————此为完成《疯狂Android》初次览后的第一次试水,也算是对前面所学知识的第一次总结性回顾
SuperProfile设计路程与问题记录
此应用旨在设计出智能的、人性化的系列情景模式,纵观应用Android市场,也找不到一款能够让人满意的情景模式软件,此想法早在2013年初识Android时就已产生


TabHost
getTabHost()
newTabSpec(String tag)
addTab(TabHost.TabSpec tabSpec)

组件style
style.xml
<resources>

    <!-- Base application theme. -->
    <style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar">
        <!-- Customize your theme here. -->
    </style>
    <style name="tab_text_view_style_test">
        <item name="android:textSize">20dp</item>
        <item name="android:layout_width">match_parent</item>
        <item name="android:layout_height">wrap_content</item>
        <item name="android:layout_centerHorizontal">true</item>
    </style>

</resources>

main.xml
<TextView
                    style="@style/tab_text_view_style_test"
                    android:text="@string/tab2_content"
                    />


手势Gesture
Activity必须
  extends TabActivity implements OnGestureListener
public abstract boolean onScroll (MotionEvent e1, MotionEvent e2, float distanceX, float distanceY)



获取string.xml文件里面的值有几个不同的地方。

1.在AndroidManifest.xml与layout等xml文件里:

android:text="@string/resource_name" 

  

2.在activity里:

方法一:this.getString(R.string.resource_name);  

方法二:getResources().getString(R.string.resource_name); 

 

3.在其他java文件(必须有Context或pplication)

方法一: context.getString(R.string.resource_name); 

方法二: application.getString(R.string.resource_name); 



隐藏APP标题栏
2.  [代码][XML]代码     
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<? xml version = "1.0" encoding = "utf-8" ?>
< manifest xmlns:android = "http://schemas.android.com/apk/res/android"
       package = "de.vogella.android.temperature"
       android:versionCode = "1"
       android:versionName = "1.0" >
     < application android:icon = "@drawable/icon" android:label = "@string/app_name" >
         < activity android:name = ".Convert"
                   android:label = "@string/app_name"
                    android:theme = "@android:style/Theme.NoTitleBar.Fullscreen" >
             < intent-filter >
                 < action android:name = "android.intent.action.MAIN" />
                 < category android:name = "android.intent.category.LAUNCHER" />
             </ intent-filter >
         </ activity >
  
     </ application >
     < uses-sdk android:minSdkVersion = "9" />
  
</ manifest >

3. [代码][Java]代码     跳至 [2] [3] [全屏预览]

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Override
public void onCreate(Bundle savedInstanceState) {
     super .onCreate(savedInstanceState);
     // hide titlebar of application
     // must be before setting the layout
     requestWindowFeature(Window.FEATURE_NO_TITLE);
     // hide statusbar of Android
     // could also be done later
     getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
             WindowManager.LayoutParams.FLAG_FULLSCREEN);
     setContentView(R.layout.main);
     text = (EditText) findViewById(R.id.EditText01);
  
}


Here's the simplest, most robust, and scalable solution to get tabs on the bottom of the screen. 

  1. In your vertical LinearLayout, put the FrameLayout above the TabWidget
  2. Set layout_height to wrap_content on both FrameLayout and TabWidget 
  3. Set FrameLayout's android:layout_weight="1"
  4. Set TabWidget's android:layout_weight="0" (0 is default, but for emphasis, readability, etc)
  5. Set TabWidget's android:layout_marginBottom="-4dp" (to remove the bottom divider)

Full code:

<?xml version="1.0" encoding="utf-8"?>
<TabHost xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@android:id/tabhost"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">

    <LinearLayout
        android:orientation="vertical"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:padding="5dp">

        <FrameLayout
            android:id="@android:id/tabcontent"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:padding="5dp"
            android:layout_weight="1"/>

        <TabWidget
            android:id="@android:id/tabs"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_weight="0"
            android:layout_marginBottom="-4dp"/>

    </LinearLayout>

</TabHost>


Encase the whole thing in:

<ScrollView
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:scrollbars="none"
    android:layout_weight="1">
    <LinearLayout
      android:layout_width="fill_parent"
      android:layout_height="fill_parent"
      android:orientation="vertical">

    ...

</ScrollView>

此方法已弃用,现在使用的都是viewpager+fragment 方式实现

在郭林blog中的qq应用演示里,旋转屏幕会导致Fragment叠加在一起,
在ActivityManifest文件中的Activity属性里添加如下代码可解决问题
              android:configChanges="orientation|keyboardHidden|screenSize"
ps: 很明显切换横竖屏时会触发oncreate事件,成员变量也会重置,因此当屏幕切换后会再次执行到setTabSelection(0);而在执行基中的hideFragments方法时messageFragment等成员变量已重置为空即hideFragments根据条件将不会执行任何代码,即换屏之前的fragment不会被hide掉,FrameLayout布局自然会将所有的fragment迭加显示了.

下面详解ViewPager + Fragment

在这里简单说明一下 FragmentStatePagerAdapter 和 FragmentPagerAdapter

2个adapter 

第一种 fragment状态adapter -  在当前只会存在   前1个fragment  当前 fragment 和 下1个 fragment   其他销毁 ,适合加载多数据

第二种 FragmentPagerAdapter  - 全部存在,所以不太适合加载 大量的数据 如图片什么的,很容易内存溢出。

如果ViewPager没有和Fragment一起,ViewPager的适配器是PagerAdapter,它是基类提供适配器来填充页面ViewPager内部,当你实现一个PagerAdapter,你必须至少覆盖以下方法:


  • 在需要添加到Activity里的Fragment,class文件中import Fragment的方法,否则会导致错误,如下
//import android.os.Bundle;
//import android.app.Fragment;//导致错误
//import android.view.LayoutInflater;
//import android.view.View;
//import android.view.ViewGroup;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;


onPageScrollStateChanged(int arg0)   ,此方法是在状态改变的时候调用,其中arg0这个参数

有三种状态(0,1,2)。arg0 ==1的时辰默示正在滑动,arg0==2的时辰默示滑动完毕了,arg0==0的时辰默示什么都没做。

当页面开始滑动的时候,三种状态的变化顺序为(1,2,0)

onPageScrolled(int arg0,float arg1,int arg2)    ,当页面在滑动的时候会调用此方法,在滑动被停止之前,此方法回一直得到

调用。其中三个参数的含义分别为:

arg0 :当前页面,及你点击滑动的页面

arg1:当前页面偏移的百分比

arg2:当前页面偏移的像素位置 


onPageSelected( int  arg0) :   此方法是页面跳转完后得到调用,arg0是你当前选中的页面的Position(位置编号,从0开始计数)

更换App标题栏图标

一般Android界面里的默认 标题栏上左边是有Logo的,且和整个app的logo一样,如果要修改该 标题图标,则需加以下代码:

 

getWindow().setFeatureDrawableResource(Window.FEATURE_LEFT_ICON, R.drawable.qq);

 

 

其中 R.drawable.qq 为自己想要更换的图标

 

注意在写改行代码之前先加一: requestWindowFeature(Window.FEATURE_LEFT_ICON);

不然会报错说没有要求Window.FEATURE_LEFT_ICON这个属性

而且该句代码要加在setContentView之前,不然也会报错说没有加在该函数之前。

 

 

 
 
   
  1. public class Test01 extends Activity { 
  2.     /** Called when the activity is first created. */ 
  3.     @Override 
  4.     public void onCreate(Bundle savedInstanceState) { 
  5.         super.onCreate(savedInstanceState); 
  6.         requestWindowFeature(Window.FEATURE_LEFT_ICON); 
  7.         setContentView(R.layout.main); 
  8.         getWindow().setFeatureDrawableResource(Window.FEATURE_LEFT_ICON, 
  9.                 R.drawable.qq); 
  10.     } 

fragment
当多个fragment重叠显示时,上层的点击事件会传递到下一层,通俗来说也就是当我们点击上层某个地方从而触发下层的某个事件。一般来说我们在加fragment时会通过replace或add方法来替换某个空FrameLayout,属于动态加载。但有时从xml中定义,通过hide()和show()来控制某个fragment的显示和隐藏,就会出现重叠问题。我们可以在上层fragment加载的布局让它获取整个焦点,从而点击事件会在上层终止
加载的方法之一是:在Fragment布局文件中添加
    android:clickable="true"

mSectionsPagerAdapter = new SectionsPagerAdapter(getActivity().getSupportFragmentManager());

在Fragment里面嵌套Fragment 的话,不要用上面的那句。。。会在ViewPager中出现。有些Fragment 不会加载的情况。。。既ViewPager 加载 Fragment 空白页的情况。。。。

所以   Fragment里面嵌套Fragment 的话:一定要用getChildFragmentManager();

  mSectionsPagerAdapter = new SectionsPagerAdapter(getChildFragmentManager());

fragment 嵌套Fragment
在此之后,是响应innerFragment里的back按钮事件
————————————————————————

When you add the fragment in your transaction you should use a tag...

fragTrans.replace(android.R.id.content, myFragment, "MY_FRAGMENT");

...and later if you want to check if the fragment is visible:

MyFragment myFragment = (MyFragment)getFragmentManager().findFragmentByTag("MY_FRAGMENT");
if (myFragment.isVisible()) {
   // add your code here
}

在onKeyDown定义为static时,内部不能再使用FragmentManager

另外,在Fragment中添加Fragment之后,管理添加的Fragment一定要用getChildFragmentManager()

在ViewPager的FragmentA之内再添加Fragment1,要在FA内做如下处理(注意是childFM)
getChildFragmentManager().beginTransaction().addToBackStack(null)
                .add(3, new Fragment3()).commit();
@Override
public void onBackPressed() {

    // If the fragment exists and has some back-stack entry
    if (mActivityDirectFragment != null && mActivityDirectFragment.getChildFragmentManager().getBackStackEntryCount() > 0){
        // Get the fragment fragment manager - and pop the backstack
        mActivityDirectFragment.getChildFragmentManager().popBackStack();
    }
    // Else, nothing in the direct fragment back stack
    else{
        // Let super handle the back press
        super.onBackPressed();          
    }
}

第一页情景模式内,监听多个按钮之后,在各个case内,不能复用getFragmentManager()
//                        FragmentTransaction transaction = getFragmentManager().beginTransaction();
//                        transaction.addToBackStack(null);
//                        transaction.commit();

应使用                        getFragmentManager().beginTransaction().addToBackStack(null).commit();


TableLayout
 android:shrinkColumnsandroid:stretchColumns的值都是以0开始的index,但必须是string值,即用"1,2,5"来表示。可以用"*"来表示all columns。而且同一column可以同时设置为shrinkable和stretchable。

如果使用TableLayout类的 setColumnShrinkable/setColumnStretchable (int columnIndex, boolean isShrinkable)就麻烦些了,需要一个一个column来设置。也可以使用TableLayout的 setShrinkAllColumns/setStretchAllColumns来设置all columns。
    判断这些column是否shrinkable或stretchable,可以调用isColumnShrinkable/isColumnStretchable(int columnIndex),isShrinkAllColumns()/isStretchAllColumns()

单元格可以为empty,并且通过android:layout_column可以设置index值实现跳开某些单元格。在TableRow之间,添加View,设置layout_height以及背景色,就可以实现一条间隔线。android:layout_span可以设置合并几个单元格



  1. 在Fragment中使用findViewById方法时,因为Fragment不继承Content,所以需要使用getActivity().findViewById(...)
  2. 在Fragment中对Fragment布局的SeekBar进行处理,处理方法应写在Fragment 的onActivityCreated方法中:
@Override
    public void onActivityCreated(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onActivityCreated(savedInstanceState);
     //do something
}


数据存储

SharedPreferences也是一种轻型的数据存储方式,它的本质是基于XML文件存储key-value键值对数据,通常用来存储一些简单的配置信息。其存储位置在/data/data/<包名>/shared_prefs目录下。SharedPreferences对象本身只能获取数据而不支持存储和修改,存储修改是通过Editor对象实现。实现SharedPreferences存储的步骤如下:

  一、根据Context获取SharedPreferences对象

  二、利用edit()方法获取Editor对象。

  三、通过Editor对象存储key-value键值对数据。

  四、通过commit()方法提交数据。

  具体实现代码如下:

复制代码
 1 publicclass MainActivity extends Activity {
2
@Override
3 publicvoid
onCreate(Bundle savedInstanceState) {
4 super
.onCreate(savedInstanceState);
5
setContentView(R.layout.main);
6

7 //获取SharedPreferences对象

8 Context ctx = MainActivity.this;
9 SharedPreferences sp = ctx.getSharedPreferences("SP"
, MODE_PRIVATE);
10 //存入数据

11 Editor editor = sp.edit();
12 editor.putString("STRING_KEY", "string"
);
13 editor.putInt("INT_KEY", 0
);
14 editor.putBoolean("BOOLEAN_KEY", true
);
15
editor.commit();
16

17 //返回STRING_KEY的值

18 Log.d("SP", sp.getString("STRING_KEY", "none"));
19 //如果NOT_EXIST不存在,则返回值为"none"

20 Log.d("SP", sp.getString("NOT_EXIST", "none"));
21
}
22 }
复制代码

   这段代码执行过后,即在/data/data/com.test/shared_prefs目录下生成了一个SP.xml文件,一个应用可以创建多个这样的xml文件。如图所示: 

   SP.xml文件的具体内容如下:

复制代码
1 <?xml version='1.0' encoding='utf-8' standalone='yes' ?>
2 <map>
3 <string name="STRING_KEY">string</string>
4 <int name="INT_KEY" value="0"/>
5 <boolean name="BOOLEAN_KEY" value="true"/>
6 </map>
复制代码

  在程序代码中,通过getXXX方法,可以方便的获得对应Key的Value值,如果key值错误或者此key无对应value值,SharedPreferences提供了一个赋予默认值的机会,以此保证程序的健壮性。如下图运行结果中因为并无值为"NOT_EXIST"的Key,所以Log打印出的是其默认值:“none”。在访问一个不存在key值这个过程中,并无任何异常抛出。  

  SharedPreferences对象与SQLite数据库相比,免去了创建数据库,创建表,写SQL语句等诸多操作,相对而言更加方便,简洁。但是SharedPreferences也有其自身缺陷,比如其职能存储boolean,int,float,long和String五种简单的数据类型,比如其无法进行条件查询等。所以不论SharedPreferences的数据存储操作是如何简单,它也只能是存储方式的一种补充,而无法完全替代如SQLite数据库这样的其他数据存储方式。



















评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值