"妹知"源码解读

来源:互联网 发布:高斯金字塔 源码 编辑:程序博客网 时间:2024/06/06 00:16

关于@TargetApi的作用,及与@SuppressLint的不同:
http://wenrisheng.iteye.com/blog/2175528

总结:
安卓开发中,在低版本SDK使用高版本的API会报错。一般处理方法是换一种实现方法,或者在高版本SDK中使用高版本API,低版本SDK中使用效果可能会差点的折衷方案;后者可以用如下技巧来实现。
步骤:
1.在使用了高版本API的方法前面加一个 @TargetApi(API号)
2.在代码上用版本判断来控制不同版本使用不同的代码

针对不同版本的Android Activity 全屏方法总结全在这里啦:
http://talentprince.github.io/blog/2015/01/07/android-activity-quan-ping-fang-fa-zong-jie/

关于发布release版本:
1.open Build Variants
2.set debug to release
3.shift+f10 run!!

实现继承自RecyclerView.Adapter的Adapter要实现三个抽象方法,onCreateViewHolder,onBindViewHolder,getItemCount。如下图:

public static class Adapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>{        //创建新View,被LayoutManager所调用        @Override        public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {            return null;        }        //将数据与界面进行绑定的操作        @Override        public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {        }        //获取数据的数量        @Override        public int getItemCount() {            return 0;        }    }

具体的实现案例参考NewsListAdapter。
详情分析:
http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2014/1118/2004.html

一般app广告图片循环控件:
https://github.com/saiwu-bigkoo/Android-ConvenientBanner

试验Fragment启动顺序的结果(待解释)

开始:05-17 15:30:42.698 6043-6043/com.zengqi.knowledge I/baseFragment: onCreateView05-17 15:30:42.718 6043-6043/com.zengqi.knowledge I/baseFragment: onActivityCreated05-17 15:30:42.718 6043-6043/com.zengqi.knowledge I/baseFragment: onstart05-17 15:30:42.768 6043-6043/com.zengqi.knowledge I/baseFragment: onCreateView05-17 15:30:42.768 6043-6043/com.zengqi.knowledge I/RecyclerFragment: initlayoutId implement05-17 15:30:42.778 6043-6043/com.zengqi.knowledge I/ZhihuFragment: initViews implement05-17 15:30:42.778 6043-6043/com.zengqi.knowledge I/RecyclerFragment: initViews implement05-17 15:30:42.778 6043-6043/com.zengqi.knowledge I/baseFragment: onActivityCreated05-17 15:30:42.778 6043-6043/com.zengqi.knowledge I/ZhihuFragment: initData implement05-17 15:30:42.808 6043-6043/com.zengqi.knowledge I/baseFragment: onstart05-17 15:30:42.808 6043-6043/com.zengqi.knowledge I/baseFragment: onCreateView05-17 15:30:42.808 6043-6043/com.zengqi.knowledge I/RecyclerFragment: initlayoutId implement05-17 15:30:42.808 6043-6043/com.zengqi.knowledge I/RecyclerFragment: initViews implement05-17 15:30:42.808 6043-6043/com.zengqi.knowledge I/baseFragment: onActivityCreated05-17 15:30:42.808 6043-6043/com.zengqi.knowledge I/baseFragment: onstart退出(切换至picFragment,其继承自RecyclerFragment,注意我没在picFragment生命周期中打Log):05-17 15:44:51.253 6043-6043/com.zengqi.knowledge I/RecyclerFragment: onPause05-17 15:44:51.253 6043-6043/com.zengqi.knowledge I/RecyclerFragment: onPause05-17 15:44:51.263 6043-6043/com.zengqi.knowledge I/ZhihuFragment: ondestroyView05-17 15:44:51.263 6043-6043/com.zengqi.knowledge I/RecyclerFragment: ondestroyView05-17 15:44:51.263 6043-6043/com.zengqi.knowledge I/baseFragment: ondestroyView05-17 15:44:51.273 6043-6043/com.zengqi.knowledge I/RecyclerFragment: ondestroyView05-17 15:44:51.273 6043-6043/com.zengqi.knowledge I/baseFragment: ondestroyView05-17 15:44:51.273 6043-6043/com.zengqi.knowledge I/baseFragment: ondestroyView05-17 15:44:51.273 6043-6043/com.zengqi.knowledge I/baseFragment: ondestroy05-17 15:44:51.273 6043-6043/com.zengqi.knowledge I/baseFragment: ondestroy05-17 15:44:51.273 6043-6043/com.zengqi.knowledge I/baseFragment: ondestroy05-17 15:44:51.273 6043-6043/com.zengqi.knowledge I/baseFragment: onCreateView05-17 15:44:51.303 6043-6043/com.zengqi.knowledge I/baseFragment: onActivityCreated05-17 15:44:51.303 6043-6043/com.zengqi.knowledge I/baseFragment: onstart05-17 15:44:51.343 6043-6043/com.zengqi.knowledge I/baseFragment: onCreateView05-17 15:44:51.343 6043-6043/com.zengqi.knowledge I/RecyclerFragment: initlayoutId implement05-17 15:44:51.343 6043-6043/com.zengqi.knowledge I/RecyclerFragment: initViews implement05-17 15:44:51.353 6043-6043/com.zengqi.knowledge I/baseFragment: onActivityCreated05-17 15:44:51.363 6043-6043/com.zengqi.knowledge I/baseFragment: onstart05-17 15:44:51.363 6043-6043/com.zengqi.knowledge I/baseFragment: onCreateView05-17 15:44:51.363 6043-6043/com.zengqi.knowledge I/RecyclerFragment: initlayoutId implement05-17 15:44:51.363 6043-6043/com.zengqi.knowledge I/RecyclerFragment: initViews implement05-17 15:44:51.373 6043-6043/com.zengqi.knowledge I/baseFragment: onActivityCreated05-17 15:44:51.373 6043-6043/com.zengqi.knowledge I/baseFragment: onstart

关于本地广播管理者LocalBroadcastManager:

/** * Helper to register for and send broadcasts of Intents to local objects * within your process.  This is has a number of advantages over sending * global broadcasts with {@link android.content.Context#sendBroadcast}: * <ul> * <li> You know that the data you are broadcasting won't leave your app, so * don't need to worry about leaking private data. * <li> It is not possible for other applications to send these broadcasts to * your app, so you don't need to worry about having security holes they can * exploit. * <li> It is more efficient than sending a global broadcast through the * system. * </ul> */ public class LocalBroadcastManager {};

fresh爬的网站是:http://jandan.net/

有关API:

//Zhihu API    public static final String BASE_URL = "http://news-at.zhihu.com/api/4/news/";    public static final String NEWS_LATEST = "http://news-at.zhihu.com/api/4/news/latest";    public static final String NEWS_BEFORE = "http://news-at.zhihu.com/api/4/news/before/";    public static final String SPLASH = "http://news-at.zhihu.com/api/4/start-image/1080*1920";//知乎每天更新不同的启动图片    //Fresh things API    public static final String FRESH_NEWS = "http://jandan.net/?oxwlxojflwblxbsapi=get_recent_posts&include=url,date,tags,author,title,comment_count,custom_fields&custom_fields=thumb_c,views&dev=1&page=";    public static final String FRESH_NEWS_DETAIL = "http://i.jandan.net/?oxwlxojflwblxbsapi=get_post&include=content&id=";    public static final String FRESH_NEWS_COMMENTS = "http://jandan.duoshuo.com/api/threads/listPosts.json?thread_key=";    public static final String TAG_H = "h";

FRESH_NEWS返回的数据格式是:
这里写图片描述
展开post:
这里写图片描述
post具体由id,url,title,date,tags,author,comment_count,custom_fields(里面的thumb_c为缩略图)组成。

FRESH_NEWS_DETAILS应该这样使用(后面跟请求detail的id):

API.FRESH_NEWS_DETAIL + freshPost.getId()

返回数据是:
这里写图片描述
注意post中的id跟上面post中的id相对应!

关于知乎API的应该这样用:

API.BASE_URL + newsItem.getId()//加idAPI.NEWS_BEFORE + date

调用before的效果:
这里写图片描述
注意此时的date返回的是输入参数date的前一天,如果输入参数的前一天还没有到,那么返回最新的数据,此时跟latest是一样的效果。
返回数据格式:date,stories(images,type,id,title,ga_prefix)

通过id得到具体的story返回的数据:
这里写图片描述
返回数据格式:body,title,image,share_url,ga_prefix,images,type(作用未知),js(供手机端的 WebView(UIWebView) 使用),css(供手机端的 WebView(UIWebView) 使用。可知,知乎日报的文章浏览界面利用 WebView(UIWebView) 实现)。

关于返回的images数组要注意:官方 API 使用数组形式。目前暂未有使用多张图片的情形出现,曾见无 images 属性的情况,请在使用中注意!

更多知乎API的分析,请移步
https://github.com/izzyleung/ZhihuDailyPurify/wiki/%E7%9F%A5%E4%B9%8E%E6%97%A5%E6%8A%A5-API-%E5%88%86%E6%9E%90。

关于GANK:
http://gank.io/api里面有各种API,供君享用。

本例中:
这里写图片描述

豆瓣美女的API用法:

API.DB_BREAST + page其他DB分类都一样

HAPI的用法:

API.H_MAIN + type + "&page=" + pagetype和page都为int

经测试,网址无法使用。

这些API中,有些是直接返回json格式的数据,有些只是网址!对于前者,可以直接通过解析json的工具进行解析,对于后者,用jsoup工具进行解析。

关于FragmentStatePagerAdapter:

Implementation of PagerAdapter that uses a Fragment to manage each page. This class also handles saving and restoring of fragment’s state.

This version of the pager is more useful when there are a large number of pages, working more like a list view. When pages are not visible to the user, their entire fragment may be destroyed, only keeping the saved state of that fragment. This allows the pager to hold on to much less memory associated with each visited page as compared to FragmentPagerAdapter at the cost of potentially more overhead when switching between pages.

When using FragmentPagerAdapter the host ViewPager must have a valid ID set.

Subclasses only need to implement getItem(int) and getCount() to have a working adapter.

关于共享元素的教程:
http://jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0113/2310.html
共4章。
在5.0之后才能实现这种变换。
关于动画transition(包含共享元素,并没有传递position的解答):
https://github.com/lgvalle/Material-Animations

大概讲了:
Android Transition Framework can be used for three main things:

1.Animate activity layout content when transitioning from one activity to another.
2.Animate shared elements (Hero views) in transitions between activities.
3.Animate view changes within same activity.

  1. Transitions between Activities
  2. Shared elements between Activities(Shared elements between fragments,Allow Transition Overlap)
  3. Animate view layout elements
  4. (Bonus) Shared elements + Circular Reveal

在stackoverflow上的问题解答(关于共享元素在viewpager中改变了,怎么传递position到启动方,例子中两者均为activity):

From what I can tell (and correct me if I’m wrong), what you are trying to achieve is basically something like this: Assume you have a MainActivity, a DetailsActivity, and an arbitrary set of images. The MainActivity displays the set of images in a grid and the DetailsActivity displays the same set of images in a horizontal ViewPager. When the user selects an image in the MainActivity, that image should transition from its position in the grid to the correct page in the second activity’s ViewPager.

The problem we want to solve is “what if the user switches pages inside the DetailsActivity“? If this happens, we want to change the shared image that will be used during the return transition. By default, the activity transition framework will use the shared element that was used during the enter transition… but the view pager’s page has changed so obviously we want to somehow override this behavior. To do so, we will need to set a SharedElementCallback in your MainActivity and DetailsActivity’s onCreate() methods and override the onMapSharedElements() method like so:

private final SharedElementCallback mCallback = new SharedElementCallback() {
@Override
public void onMapSharedElements(List names, Map

private final SharedElementCallback mCallback = new SharedElementCallback() {        @Override        public void onMapSharedElements(List<String> names, Map<String, View> sharedElements) {            if (mTmpReenterState != null) {                int startingPosition = mTmpReenterState.getInt(EXTRA_STARTING_ALBUM_POSITION);                int currentPosition = mTmpReenterState.getInt(EXTRA_CURRENT_ALBUM_POSITION);                if (startingPosition != currentPosition) {                    // If startingPosition != currentPosition the user must have swiped to a                    // different page in the DetailsActivity. We must update the shared element                    // so that the correct one falls into place.                    //需要改动共享元素                    String newTransitionName = ALBUM_NAMES[currentPosition];                    View newSharedElement = mRecyclerView.findViewWithTag(newTransitionName);                    if (newSharedElement != null) {                        //清空再添加                        names.clear();                        names.add(newTransitionName);                        //清空再添加                        sharedElements.clear();                        sharedElements.put(newTransitionName, newSharedElement);                    }                }                mTmpReenterState = null;            } else {                // If mTmpReenterState is null, then the activity is exiting.                View navigationBar = findViewById(android.R.id.navigationBarBackground);                View statusBar = findViewById(android.R.id.statusBarBackground);                if (navigationBar != null) {                    //name和sharedElements都添加                    names.add(navigationBar.getTransitionName());                    sharedElements.put(navigationBar.getTransitionName(), navigationBar);                }                if (statusBar != null) {                    //name和sharedElements都添加                    names.add(statusBar.getTransitionName());                    sharedElements.put(statusBar.getTransitionName(), statusBar);                }            }        }    };@Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        //退出        setExitSharedElementCallback(mCallback);        }

DetailActivity:

private final SharedElementCallback mCallback = new SharedElementCallback() {        @Override        public void onMapSharedElements(List<String> names, Map<String, View> sharedElements) {            if (mIsReturning) {                ImageView sharedElement = mCurrentDetailsFragment.getAlbumImage();                if (sharedElement == null) {                    // If shared element is null, then it has been scrolled off screen and                    // no longer visible. In this case we cancel the shared element transition by                    // removing the shared element from the shared elements map.                    //共享元素不在屏幕内                    names.clear();                    sharedElements.clear();                } else if (mStartingPosition != mCurrentPosition) {                    // If the user has swiped to a different ViewPager page, then we need to                    // remove the old shared element and replace it with the new shared element                    // that should be transitioned instead.                    //替换旧的共享元素                    names.clear();                    names.add(sharedElement.getTransitionName());                    sharedElements.clear();                    sharedElements.put(sharedElement.getTransitionName(), sharedElement);                }            }        }    }; @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        //viewpager        setContentView(R.layout.activity_details);        postponeEnterTransition();        //进入        setEnterSharedElementCallback(mCallback);        }

注意:By default, the activity transition framework will use the shared element that was used during the enter transition…
所以要动态的改变position,改变共享元素,通过两个activity间的通信,我们能够使得共享元素一致。
碰到的问题
项目中MainActivity和DetailsActivity都定义了共享元素的callback。从MainActivity到DetailActivity时,传递初始position,在DetailActivity中改变了position时,能够通过回调onActivityReenter方法将改变传给MainActivity,这样就能够保持共享元素一致了。在MainActivity的onCreate中只指明了
但是,我的启动方是fragment,并没有onActivityReenter方法,唯一可能有点关系的就是onActivityResult方法了,但是好像又不对。且包含我的fragment的activity又不容易获得。这样在DetailActivity中的变化始终不能够传递给我的fragment。怎么办呢?
试验,测试看看在mainActivity中替换掉onActivityReenter方法为onActivityResult方法,如果替换后结果一致的话,就可以仿照着重写启动方fragment的onActivityResult方法,在这里面接受实时的position。但是试验结果显示不能替换:

正常情况(只有onActivityReenter):05-25 16:29:24.893 13109-13109/com.adp.activity.transitions I/main: start only05-25 16:29:31.910 13109-13109/com.adp.activity.transitions I/main: reenter05-25 16:29:31.934 13109-13109/com.adp.activity.transitions I/main: pos 705-25 16:29:31.934 13109-13109/com.adp.activity.transitions I/main: name The King of Limbs05-25 16:29:37.298 13109-13109/com.adp.activity.transitions I/main: start only05-25 16:29:44.476 13109-13109/com.adp.activity.transitions I/main: reenter05-25 16:29:44.503 13109-13109/com.adp.activity.transitions I/main: pos 705-25 16:29:44.504 13109-13109/com.adp.activity.transitions I/main: name The King of Limbs两个共存,直接崩溃:05-25 16:31:21.303 18200-18200/com.adp.activity.transitions I/main: start for result05-25 16:31:27.477 18200-18200/com.adp.activity.transitions I/main: reenter05-25 16:31:27.527 18200-18200/com.adp.activity.transitions I/main: pos 705-25 16:31:27.527 18200-18200/com.adp.activity.transitions I/main: name The King of Limbs05-25 16:31:28.149 18200-18200/com.adp.activity.transitions I/main: result只有onActivityResult,直接崩溃:05-25 16:32:56.581 18992-18992/com.adp.activity.transitions I/main: start for result05-25 16:33:01.017 19321-19409/? I/DomainManager(MiLinkSDK)(games): startResolve05-25 16:33:01.019 19321-19409/? I/DomainManager(MiLinkSDK)(games): startDefaultHostThread05-25 16:33:01.104 19321-19498/? W/DomainManager(MiLinkSDK)(games): domain [domain = migc.g.mi.com,ip = 120.134.33.238,client localDNS = [none,none;202.204.48.6;202.204.60.10], errCode=0,timecost = 79ms]05-25 16:33:03.128 18992-18992/com.adp.activity.transitions I/main: result测试log:Log.i("main","start only");startActivity(intent,bundle);Log.i("main","start for result");startActivityForResult(intent, 1, bundle);

关于tint(和颜色有关):
http://blog.csdn.net/u010687392/article/details/47399719

在xml中配置android:transitionGroup=”true”应该是在transition时将其看做整体部分。

android中xml tools属性详解
http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0309/2567.html

完美解决android studio 关于中文乱码的问题:
http://www.androidchina.net/3024.html

关于onActivityReenter方法:
Called when an activity you launched with an activity transition exposes this Activity through a returning activity transition, giving you the resultCode and any additional data from it. This method will only be called if the activity set a result code other than RESULT_CANCELED and it supports activity transitions with FEATURE_ACTIVITY_TRANSITIONS.

The purpose of this function is to let the called Activity send a hint about its state so that this underlying Activity can prepare to be exposed. A call to this method does not guarantee that the called Activity has or will be exiting soon. It only indicates that it will expose this Activity’s Window and it has some data to pass to prepare it.

跟我问题一样
https://github.com/alexjlockwood/activity-transitions/issues/2

可以看看
https://70kg.info/2015/11/05/SharedElement%E7%9A%84%E4%BD%BF%E7%94%A8/
http://www.yzjingying.net/4655428014.htm
http://www.yzjingying.net/561628986.htm

0 0
原创粉丝点击