【0096】【项目实战】-【开源中国】-【02】

1.BaseListFragment的封装分析-重新听

【带有listView的加载数据的抽取】每个界面都有listView的加载数据和下拉刷新的加载的效果

 

2.SwipeRefreshLayout的使用

.

 【源码】

【设置一个右侧的边框】

 【对比说明】Drawer只可以覆盖半个,必须留有边框;

Sliding pane layout 可以完全覆盖整个Activity;

 

【SwipRefreshLayout】效果

 

 【源码】/Support4Demos-19/src/com/example/android/supportv4/widget/SwipeRefreshLayoutActivity.java

  1 /*
  2  * Copyright (C) 2013 The Android Open Source Project
  3  *
  4  * Licensed under the Apache License, Version 2.0 (the "License");
  5  * you may not use this file except in compliance with the License.
  6  * You may obtain a copy of the License at
  7  *
  8  *      http://www.apache.org/licenses/LICENSE-2.0
  9  *
 10  * Unless required by applicable law or agreed to in writing, software
 11  * distributed under the License is distributed on an "AS IS" BASIS,
 12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13  * See the License for the specific language governing permissions and
 14  * limitations under the License.
 15  */
 16 
 17 package com.example.android.supportv4.widget;
 18 
 19 import android.app.Activity;
 20 import android.os.Bundle;
 21 import android.os.Handler;
 22 import android.support.v4.widget.SwipeRefreshLayout;
 23 import android.view.Menu;
 24 import android.view.MenuInflater;
 25 import android.view.MenuItem;
 26 import android.view.MotionEvent;
 27 import android.view.View;
 28 import android.view.View.OnClickListener;
 29 import android.widget.ArrayAdapter;
 30 import android.widget.Button;
 31 import android.widget.ListView;
 32 import android.widget.Toast;
 33 
 34 import com.example.android.supportv4.R;
 35 import com.example.android.supportv4.Shakespeare;
 36 
 37 import android.support.v4.widget.SwipeRefreshLayout.OnRefreshListener;
 38 
 39 /**
 40  * Example of using the SwipeRefreshLayout.
 41  */
 42 public class SwipeRefreshLayoutActivity extends Activity implements OnRefreshListener { //【1】继承与Activity
 43     public static final String[] TITLES =
 44     {
 45             "Henry IV (1)",
 46             "Henry V",
 47             "Henry VIII",
 48             "Richard II",
 49             "Richard III",
 50             "Merchant of Venice",
 51             "Othello",
 52             "King Lear",
 53             "Henry IV (1)",
 54             "Henry V",
 55             "Henry VIII",
 56             "Richard II",
 57             "Richard III",
 58             "Merchant of Venice",
 59             "Othello",
 60             "King Lear",
 61             "Henry IV (1)",
 62             "Henry V",
 63             "Henry VIII",
 64             "Richard II",
 65             "Richard III",
 66             "Merchant of Venice",
 67             "Othello",
 68             "King Lear",
 69             "Henry IV (1)",
 70             "Henry V",
 71             "Henry VIII",
 72             "Richard II",
 73             "Richard III",
 74             "Merchant of Venice",
 75             "Othello",
 76             "King Lear"
 77     };
 78     // Try a SUPER quick refresh to make sure we don't get extra refreshes
 79     // while the user's finger is still down.
 80     private static final boolean SUPER_QUICK_REFRESH = false;
 81     private View mContent;
 82     private SwipeRefreshLayout mSwipeRefreshWidget;
 83     private ListView mList;
 84     private Handler mHandler = new Handler();
 85     private final Runnable mRefreshDone = new Runnable() {
 86 
 87         @Override
 88         public void run() {
 89             mSwipeRefreshWidget.setRefreshing(false); //【8】结束刷新
 90         }
 91 
 92     };
 93     @Override
 94     public void onCreate(Bundle bundle) {
 95         super.onCreate(bundle);
 96         setContentView(R.layout.swipe_refresh_widget_sample);
 97         mSwipeRefreshWidget = (SwipeRefreshLayout) findViewById(R.id.swipe_refresh_widget);
 98         mSwipeRefreshWidget.setColorScheme(R.color.color1, R.color.color2, R.color.color3,  //【2】设置四个颜色条
 99                 R.color.color4);
100         mList = (ListView) findViewById(R.id.content);
101         ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(this,
102                 android.R.layout.simple_list_item_1, android.R.id.text1, TITLES); //【3】设置适配器adpater;
103         mList.setAdapter(arrayAdapter); //设置适配器
104         mSwipeRefreshWidget.setOnRefreshListener(this); //【4】设置监听事件,在42行的时候SwipeRefreshLayoutActivity实现了OnRefreshListener
105     }
106 
107     @Override
108     public void onRefresh() { //【5】下拉刷新的时候调用此方法
109         refresh();//【6】调用了136行、137行的方法;
110     }
111 
112 
113     @Override
114     public boolean onCreateOptionsMenu(Menu menu) {
115         MenuInflater inflater = getMenuInflater();
116         inflater.inflate(R.menu.swipe_refresh_menu, menu);
117         return true;
118     }
119 
120     /**
121      * Click handler for the menu item to force a refresh.
122      */
123     @Override
124     public boolean onOptionsItemSelected(MenuItem item) {
125         final int id = item.getItemId();
126         switch(id) {
127             case R.id.force_refresh:
128                 mSwipeRefreshWidget.setRefreshing(true);
129                 refresh();
130                 return true;
131         }
132         return false;
133     }
134 
135     private void refresh() {
136         mHandler.removeCallbacks(mRefreshDone); //移除之前的任务
137         mHandler.postDelayed(mRefreshDone, 1000);// 【7】延时执行85行的方法
138     }
139 }

 【布局】

【说明】android.support.v4.widget.SwipeRefreshLayout中可以包括任何的主界面的控件,此处包裹的是listView;包裹谁谁就可以下拉刷新;

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <!-- Copyright (C) 2013 The Android Open Source Project
 3 
 4      Licensed under the Apache License, Version 2.0 (the "License");
 5      you may not use this file except in compliance with the License.
 6      You may obtain a copy of the License at
 7 
 8           http://www.apache.org/licenses/LICENSE-2.0
 9 
10      Unless required by applicable law or agreed to in writing, software
11      distributed under the License is distributed on an "AS IS" BASIS,
12      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13      See the License for the specific language governing permissions and
14      limitations under the License.
15 -->
16 
17 <android.support.v4.widget.SwipeRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
18     android:id="@+id/swipe_refresh_widget"
19     android:layout_width="match_parent"
20     android:layout_height="match_parent">
21     <!-- some full screen pullable view that will be the offsetable content -->
22     <ListView
23         android:layout_width="match_parent"
24         android:layout_height="match_parent"
25         android:id="@+id/content"/>
26 </android.support.v4.widget.SwipeRefreshLayout>

【5.0之后的效果】变为了圆圈;

3.android动画总结

 1 四.android动画总结
 2 1.补间动画:TranslationAnimation,RotationAnimation,AlphaAnimation,ScaleAnimation;
 3   缺点:早期的补间动画绘制出来的效果其实并没有真正改变View的属性,只是系统临时绘制
 4        出来的效果;
 5 2.属性动画:3.0之后谷歌提出,属性动画就是用新增的属性(如translationX,translationY,
 6             scaleX,scaleY,rotation,rotationX等等)用来记录view的改变的值;这样就允许
 7             动画能保存并持续进行;
 8 3.与属性动画相关的类和方法:
 9     a.更改view属性的方法:
10     view.setTranslationX(x);//3.0之后的方法
11     ViewHelper.setTranslationX(view,x);//NineOldAndroid动画类库中的类
12     
13     b.ValueAnimatior和ObjectAnimatior;
14     ObjectAnimatior允许你直接更改View的新属性;
15     ValueAnimatior只是帮你定义和执行动画流程,并没有实现任何的动画逻辑,需要
16     你添加动画更新的监听,在执行过程中进行自定义的动画逻辑;
17     
18     c.ViewPropertyAnimator:一般用NineOldAndroid中的类,它简化了ObjectAnimator
19       类的操作,然后直接运行我们执行更改View属性的动画;
20       ViewPropertyAnimator.animate(view).translationX(10).setDuration(300).start();

3.1.缩放动画的不同实现

【布局】

【ObjectAnimator变宽】此类只能使用的3.0之上,不兼容低版本的;

 

 【ViewPropertyAnimator的实现】

[效果]具有,缩放动画,最后弹性显示

3.2 平移动画

【差值效果】像球弹起一样

 

 【差值效果】左右震动

[效果]左右抖动,类似的使用场景是输入密码错误的文本框;

 【文本框从屏幕上面隐藏的状态滑动到屏幕的指定的位置】

【修改优化】

 

【说明】在属性动画执行的时候,控件本身的left、top值是没有改变的,此属性的坐标系参考的是父类的坐标系;、

但是,属性动画的坐标的transX和transX移动的时候参考的坐标系是自身的坐标系,发生了改变;

【打印结果】看出在translationBy之后的top值仍然是顶在了Activity的顶部,没有改变;

 4.网络框架的封装

【说明】在项目中的封装,分为原始的封装---系统层的封装---业务的封装;在实际的项目中都会封装到最后的业务层

4.1 方式2的封装-调用

【方式2的封装-调用】

【方式2的封装-调用】

4.2 方式3的封装

 

  1 package com.itheima.oschina.api.remote;
  2 
  3 import java.io.File;
  4 import java.io.FileNotFoundException;
  5 
  6 import org.kymjs.kjframe.utils.KJLoger;
  7 
  8 import android.text.TextUtils;
  9 
 10 import com.itheima.oschina.AppContext;
 11 import com.itheima.oschina.api.ApiHttpClient;
 12 import com.itheima.oschina.bean.BlogList;
 13 import com.itheima.oschina.bean.Tweet;
 14 import com.itheima.oschina.bean.TweetsList;
 15 import com.itheima.oschina.util.TLog;
 16 import com.loopj.android.http.AsyncHttpResponseHandler;
 17 import com.loopj.android.http.RequestParams;
 18 
 19 public class OSChinaApi {  //再次封装
 20 
 21     /**
 22      * 登陆
 23      * 
 24      * @param username
 25      * @param password
 26      * @param handler
 27      */
 28     public static void login(String username, String password,
 29             AsyncHttpResponseHandler handler) {
 30         RequestParams params = new RequestParams();
 31         params.put("username", username);
 32         params.put("pwd", password);
 33         params.put("keep_login", 1);
 34         String loginurl = "action/api/login_validate";
 35         ApiHttpClient.post(loginurl, params, handler);
 36     }
 37 
 38     /**
 39      * 获取新闻列表
 40      * 
 41      * @param catalog
 42      *            类别 (1,2,3)
 43      * @param page
 44      *            第几页
 45      * @param handler
 46      */
 47     public static void getNewsList(int catalog, int page,
 48             AsyncHttpResponseHandler handler) {
 49         RequestParams params = new RequestParams();
 50 //        params.put("catalog", catalog);
 51 //        params.put("pageIndex", page);
 52 //        params.put("pageSize", AppContext.PAGE_SIZE);
 53 //        if (catalog == NewsList.CATALOG_WEEK) {
 54 //            params.put("show", "week");
 55 //        } else if (catalog == NewsList.CATALOG_MONTH) {
 56 //            params.put("show", "month");
 57 //        }
 58 //        
 59 //        ApiHttpClient.get("action/api/news_list", params, handler);
 60 
 61         TLog.log("getNewsList: catalog: " + catalog + " page: " + page);
 62         String path = "";
 63         switch (catalog) {  //根据类别的信息进行path的拼接
 64         case 1:
 65             path = "oschina/list/news/page"+page+".xml";
 66             break;
 67         case 4:
 68             path = "oschina/list/hotspot/page"+page+".xml";
 69             break;
 70         }
 71 
 72         ApiHttpClient.getLocal(path, params, handler); //调用第二种方式中的封装;
 73     }
 74 
 75     public static void getBlogList(String type, int pageIndex,
 76             AsyncHttpResponseHandler handler) {
 77         RequestParams params = new RequestParams();
 78 //        params.put("type", type);
 79 //        params.put("pageIndex", pageIndex);
 80 //        params.put("pageSize", AppContext.PAGE_SIZE);
 81 //        ApiHttpClient.get("action/api/blog_list", params, handler);
 82         
 83         String path = "";
 84         if(BlogList.CATALOG_LATEST.equals(type)){
 85             path = "oschina/list/blog/page"+pageIndex+".xml";
 86         }else if (BlogList.CATALOG_RECOMMEND.equals(type)) {
 87             path = "oschina/list/recommend/page"+pageIndex+".xml";
 88         }
 89         
 90         ApiHttpClient.getLocal(path, params, handler);
 91     }

  4.3. 手机客户端信息的传递和获取

4.4.网络二次封装

4.5【封装的好处】

【好处】替换第三方的框架,可以直接封装,到时候直接替换库就可以

【替换第三方开发的库】只需要修改方法的参数和定义的类就可以

5.自定义对话框

5.1 效果及分析

【效果】可以使用popWindow(剩余部分的黑色透明部分显示的时候没有渐变的效果,需要增加动画)、对话框、Acvitity实现(消耗内存大);

【此处使用的对话框】

 

【说明】此处的对话框,与之前遇到的对话框不一样;

【位置】之前的弹出位置在屏幕中间;现在在底部;

【占据屏幕比例】之前在四周围都有距离,现在的占满屏幕的下半部分;

 

5.2 自定义对话框的构造

【继承与Dialog】

 

【完成动画的定义】

 

【进入动画】

【退出动画】

【初始化View对象】加载布局

[布局源码]

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3     android:id="@+id/set_pop"
 4     android:layout_width="match_parent"
 5     android:layout_height="wrap_content" >
 6 
 7     <LinearLayout
 8         android:id="@+id/ll_option_container"
 9         android:layout_width="match_parent"
10         android:layout_height="wrap_content"
11         android:orientation="vertical" >
12 
13         <LinearLayout
14             android:layout_width="match_parent"
15             android:layout_height="wrap_content"
16             android:orientation="horizontal" >
17 
18             <LinearLayout
19                 android:id="@+id/ly_quick_option_text"
20                 style="@style/quick_option_item" >
21 
22                 <ImageView
23                     android:layout_width="wrap_content"
24                     android:layout_height="wrap_content"
25                     android:src="@drawable/quickoption_icon_text_selector" />
26 
27                 <TextView
28                     style="@style/quick_option_item_text"
29                     android:text="@string/quick_option_text" />
30             </LinearLayout>
31 
32             <LinearLayout
33                 android:id="@+id/ly_quick_option_album"
34                 style="@style/quick_option_item" >
35 
36                 <ImageView
37                     android:layout_width="wrap_content"
38                     android:layout_height="wrap_content"
39                     android:src="@drawable/quickoption_icon_album_selector" />
40 
41                 <TextView
42                     style="@style/quick_option_item_text"
43                     android:text="@string/quick_option_album" />
44             </LinearLayout>
45 
46             <LinearLayout
47                 android:id="@+id/ly_quick_option_photo"
48                 style="@style/quick_option_item" >
49 
50                 <ImageView
51                     android:layout_width="wrap_content"
52                     android:layout_height="wrap_content"
53                     android:background="@null"
54                     android:src="@drawable/quickoption_icon_photo_selector" />
55 
56                 <TextView
57                     style="@style/quick_option_item_text"
58                     android:text="@string/quick_option_photo" />
59             </LinearLayout>
60         </LinearLayout>
61 
62     </LinearLayout>
63 
64     <LinearLayout
65         android:id="@+id/ll_foot"
66         android:layout_width="match_parent"
67         android:layout_height="wrap_content"
68         android:layout_below="@id/ll_option_container"
69         android:background="@color/list_item_background_normal"
70         android:gravity="center"
71         android:padding="10dip"
72         android:visibility="visible" >
73 
74         <ImageView
75             android:id="@+id/iv_close"
76             android:layout_width="35dp"
77             android:layout_height="35dp"
78             android:contentDescription="@null"
79             android:focusable="false"
80             android:src="@drawable/btn_quickoption_route" />
81     </LinearLayout>
82 
83 </RelativeLayout>

【增加点击按钮的旋转动画】

【点击界面的其他部分消失】点击除了按钮(相册、拍照、文字按钮)之外的任何地方都可以使得对话框消失;

【但是点击按钮之后的子控件可以显示效果】因为按钮是对话框的子控件,子控件将事件进行了拦截;

 

 【设置布局】

【设置对话框在底部】默认是在中间;

【设置对话框和当前屏幕的宽度一致】

6.自定义ActionBar的内容

6.1 demo

 【自定义ActionBar】在详情页中存在一个自定义的ActionBar,需要自定义箭头--竖线--文字;

 【自定义一个ActionBar】

【设定充满整个ActonBar的标题栏】

 6.2 项目中的使用

【设置标题栏的占据整个的宽度】设置参数

7.WebView高级处理

7.1 查找某个正在运行的Activity的方法

【直接查看日志信息】

7.2 子类的初始化

【说明】Activity只是一个容器,fragment是其中要填充的内容;

【新闻详情页的中的WebView】

【布局中的WebView】

【WebView的初始化】增加一个WebViewClient,并且可以增加超链接的跳转;

7.3 父类的逻辑

【逻辑分析】在子类中仅仅执行了init初始化的任务,其他的逻辑是在父类中执行的;

 7.3.1【请求数据】

 

【子类方法中传递的关键参数】

【mHandler】核心是更新UI的操作;

 

【更新UI】executOnLoadDataSuccess()方法

7.3.2 [子类复写该方法]核心代码:fillWebViewBody之图片的加载

【获取的html的中body信息】

 

 

【WebView对html中的图片的显示】其中存在java代码与js代码的交互,比较麻烦;

【参考文档】java代码和js代码的交互

Android 中可以通过webview来实现和js的交互,在程序中调用js代码,只需要将webview控件的支持js的属性设置为true

 

Android(Java)与 JavaScript(HTML)交互有四种情况:

1) Android(Java)调用HTML中js代码

2) Android(Java)调用HTML中js代码(带参数)

3) HTML中js调用Android(Java)代码

4) HTML中js调用Android(Java)代码(带参数)

 

下面示例总结这四种情况,直接上干货:

1) Android(Java)

 js(HTML)

4) 代码解析:

(1) 允许Android执行js脚本设置

Android(Java)与js(HTML)交互的接口函数是: mWebView.addJavascriptInterface(getHtmlObject(), "jsObj");     // jsObj 为桥连对象

Android容许执行js脚本需要设置: webSettings.setJavaScriptEnabled(true);

 

 

(2) js(HTML)访问Android(Java)代码

js(HTML)访问Android(Java)端代码是通过jsObj对象实现的,调用jsObj对象中的函数,如: window.jsObj.HtmlcallJava()

 

 

(3) Android(Java)访问js(HTML)代码

Android(Java)访问js(HTML)端代码是通过loadUrl函数实现的,访问格式如:mWebView.loadUrl("javascript: showFromHtml()");

 

说明:

1) Android访问url网址,需在AndroidManifest.xml文件,配置容许访问网络的权限:
<uses-permission android:name="android.permission.INTERNET" />

 

2) Android(Java)调用js(HTML)时,使用的mWebView.loadUrl("javascript: showFromHtml()");函数需在UI线程运行,因为mWebView为UI控件

 

 7.3.3继续分析fillWebViewBody

【网页文本样式的替换】为了使得大网页的界面可以适配手机屏幕的显示;

 

posted @ 2018-03-20 09:49  OzTaking  阅读(279)  评论(0)    收藏  举报