TouTiao开源项目 分析笔记16 新闻评论
1.要达到的效果
1.1.主要效果图
点击了标题栏的消息图标后,然后会跳转到评论详情的页面。
1.2.触发的点击事件
在新闻详情的片段中的菜单点击事件中
设置上方标题栏的消息标的监听事件
- case R.id.action_open_comment:
- NewsCommentActivity.launch(bean.getGroup_id() + "", bean.getItem_id() + "");
- break;
bean就是某一个新闻的一些属性,从最前面item中传递过来的。
2.新闻评论详情活动
2.1.源代码
- class NewsCommentActivity : BaseActivity() {
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- setContentView(R.layout.container)
- val intent = intent
- supportFragmentManager.beginTransaction()
- .replace(R.id.container,
- NewsCommentFragment.newInstance(intent.getStringExtra(ARG_GROUPID), intent.getStringExtra(ARG_ITEMID)))
- .commit()
- }
- companion object {
- private val TAG = "NewsCommentActivity"
- private val ARG_GROUPID = "groupId"
- private val ARG_ITEMID = "itemId"
- fun launch(groupId: String, itemId: String) {
- InitApp.AppContext.startActivity(Intent(InitApp.AppContext, NewsCommentActivity::class.java)
- .putExtra(ARG_GROUPID, groupId)
- .putExtra(ARG_ITEMID, itemId)
- .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK))
- }
- }
- }
2.2.外部启动这个评论活动的一个静态launch函数。
这里需要将两个关键的参数保存起来,之后在评论中会用到。
2.3.然后是一个onCreate函数,这个活动优先执行。
将container替换成片段的布局。
2.4.在清单中配置这个活动
- <activity
- android:name=".module.news.comment.NewsCommentActivity"
- android:configChanges="orientation|screenSize|uiMode"
- android:label="@string/title_comment"
- android:theme="@style/AppTheme.NoActionBar.Slidable"/>
3.新闻评论的片段
3.1.底层接口==>INewsComment
- public interface INewsComment {
- interface View extends IBaseListView<Presenter> {
- /**
- * 请求数据
- */
- void onLoadData();
- }
- interface Presenter extends IBasePresenter {
- /**
- * 请求数据
- */
- void doLoadData(String... groupId_ItemId);
- /**
- * 再起请求数据
- */
- void doLoadMoreData();
- /**
- * 设置适配器
- */
- void doSetAdapter(List<NewsCommentBean.DataBean.CommentBean> list);
- /**
- * 加载完毕
- */
- void doShowNoMore();
- }
- }
3.2.新闻评论片段源代码
- public class NewsCommentFragment extends BaseListFragment<INewsComment.Presenter> implements INewsComment.View{
- private static final String GROUP_ID = "groupId";
- private static final String ITEM_ID = "itemId";
- private static final String TAG = "NewsCommentFragment";
- private String groupId;
- private String itemId;
- public static NewsCommentFragment newInstance(String groupId, String itemId) {
- NewsCommentFragment instance = new NewsCommentFragment();
- Bundle bundle = new Bundle();
- bundle.putString(GROUP_ID, groupId);
- bundle.putString(ITEM_ID, itemId);
- instance.setArguments(bundle);
- return instance;
- }
- @Override
- protected int attachLayoutId() {
- return R.layout.fragment_list_toolbar;
- }
- @Override
- protected void initData() {
- Bundle arguments = getArguments();
- groupId = arguments.getString(GROUP_ID);
- itemId = arguments.getString(ITEM_ID);
- onLoadData();
- }
- @Override
- public void onLoadData() {
- onShowLoading();
- presenter.doLoadData(groupId, itemId);
- }
- @Override
- public void onRefresh() {
- presenter.doRefresh();
- }
- @Override
- protected void initView(View view) {
- super.initView(view);
- Toolbar toolbar = view.findViewById(R.id.toolbar);
- initToolBar(toolbar, true, getString(R.string.title_comment));
- toolbar.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- recyclerView.smoothScrollToPosition(0);
- }
- });
- toolbar.setBackgroundColor(SettingUtil.getInstance().getColor());
- adapter = new MultiTypeAdapter(oldItems);
- Register.registerNewsCommentItem(adapter);
- recyclerView.setAdapter(adapter);
- recyclerView.addOnScrollListener(new OnLoadMoreListener() {
- @Override
- public void onLoadMore() {
- if (canLoadMore) {
- canLoadMore = false;
- presenter.doLoadMoreData();
- }
- }
- });
- setHasOptionsMenu(true);
- }
- @Override
- public void onSetAdapter(final List<?> list) {
- Items newItems = new Items(list);
- newItems.add(new LoadingBean());
- DiffCallback.notifyDataSetChanged(oldItems, newItems, DiffCallback.NEWS_COMMENT, adapter);
- oldItems.clear();
- oldItems.addAll(newItems);
- canLoadMore = true;
- }
- @Override
- public void setPresenter(INewsComment.Presenter presenter) {
- if (null == presenter) {
- this.presenter = new NewsCommentPresenter(this);
- }
- }
- @Override
- public void fetchData() {
- }
- }
3.3.新建一个实例,供外部调用。
传进来两个参数,一个groupId,一个itemId。
传出去一个片段Fragment。
3.4.重写返回片段的布局==>fragment_list_toolbar.xml。
- <?xml version="1.0" encoding="utf-8"?>
- <android.support.design.widget.CoordinatorLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:app="http://schemas.android.com/apk/res-auto"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="@color/windowBackground"
- android:fitsSystemWindows="true"
- android:orientation="vertical">
- <include layout="@layout/toolbar"/>
- <android.support.v4.widget.SwipeRefreshLayout
- android:id="@+id/refresh_layout"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- app:layout_behavior="@string/appbar_scrolling_view_behavior">
- <android.support.v7.widget.RecyclerView
- android:id="@+id/recycler_view"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:fadeScrollbars="true"
- android:scrollbarFadeDuration="1"
- android:scrollbars="vertical"
- app:layoutManager="LinearLayoutManager">
- </android.support.v7.widget.RecyclerView>
- </android.support.v4.widget.SwipeRefreshLayout>
- </android.support.design.widget.CoordinatorLayout>
预览页面:
3.5.初始化视图initView。
传进去一个view。
获取toolbar+点击事件。
新建一个adapter,给recycleView设置适配器+滑动监听事件。
设置菜单。
3.6.初始化数据initData。
获取存放在bundle中的两个信息。
然后调用处理器来加载数据。
3.7.重写onRefresh函数。
调用处理器的刷新。
3.8.重写加载函数onLoadData。
显示视图的加载圈。
然后调用处理器的加载数据函数。
3.9.重写设置适配器。
传入一个List。
比较新老数据,动态变化数据。
3.10.重写设置处理器。
传入一个底层接口中定义的一个处理器。
将这个处理器保存起来以后用。
3.11.重写填充数据的fetchData。
里面是空的。这里不做任何事情。
4.新闻评论的处理器
4.1.源代码
- package com.jasonjan.headnews.module.news.comment;
- import com.jasonjan.headnews.api.IMobileNewsApi;
- import com.jasonjan.headnews.bean.news.NewsCommentBean;
- import com.jasonjan.headnews.main.ErrorAction;
- import com.jasonjan.headnews.main.RetrofitFactory;
- import java.util.ArrayList;
- import java.util.List;
- import io.reactivex.android.schedulers.AndroidSchedulers;
- import io.reactivex.annotations.NonNull;
- import io.reactivex.functions.Consumer;
- import io.reactivex.functions.Function;
- import io.reactivex.schedulers.Schedulers;
- /**
- * Created by JasonJan on 2018/1/9.
- */
- public class NewsCommentPresenter implements INewsComment.Presenter{
- private static final String TAG = "NewsCommentPresenter";
- private INewsComment.View view;
- private String groupId;
- private String itemId;
- private int offset = 0;
- private List<NewsCommentBean.DataBean.CommentBean> commentsBeanList = new ArrayList<>();
- public NewsCommentPresenter(INewsComment.View view) {
- this.view = view;
- }
- @Override
- public void doLoadData(String... groupId_ItemId){
- try {
- if (null == this.groupId) {
- this.groupId = groupId_ItemId[0];
- }
- if (null == this.itemId) {
- this.itemId = groupId_ItemId[1];
- }
- } catch (Exception e) {
- ErrorAction.print(e);
- }
- RetrofitFactory.getRetrofit().create(IMobileNewsApi.class)
- .getNewsComment(groupId, offset)
- .subscribeOn(Schedulers.io())
- .map(new Function<NewsCommentBean, List<NewsCommentBean.DataBean.CommentBean>>() {
- @Override
- public List<NewsCommentBean.DataBean.CommentBean> apply(@NonNull NewsCommentBean newsCommentBean) throws Exception {
- List<NewsCommentBean.DataBean.CommentBean> data = new ArrayList<>();
- for (NewsCommentBean.DataBean bean : newsCommentBean.getData()) {
- data.add(bean.getComment());
- }
- return data;
- }
- })
- .compose(view.<List<NewsCommentBean.DataBean.CommentBean>>bindToLife())
- .observeOn(AndroidSchedulers.mainThread())
- .subscribe(new Consumer<List<NewsCommentBean.DataBean.CommentBean>>() {
- @Override
- public void accept(@NonNull List<NewsCommentBean.DataBean.CommentBean> list) throws Exception {
- if (null != list && list.size() > 0) {
- doSetAdapter(list);
- } else {
- doShowNoMore();
- }
- }
- }, new Consumer<Throwable>() {
- @Override
- public void accept(@NonNull Throwable throwable) throws Exception {
- doShowNetError();
- ErrorAction.print(throwable);
- }
- });
- }
- @Override
- public void doLoadMoreData() {
- offset += 20;
- doLoadData();
- }
- @Override
- public void doSetAdapter(List<NewsCommentBean.DataBean.CommentBean> list) {
- commentsBeanList.addAll(list);
- view.onSetAdapter(commentsBeanList);
- view.onHideLoading();
- }
- @Override
- public void doRefresh() {
- if (commentsBeanList.size() != 0) {
- commentsBeanList.clear();
- offset = 0;
- }
- doLoadData();
- }
- @Override
- public void doShowNetError() {
- view.onHideLoading();
- view.onShowNetError();
- }
- @Override
- public void doShowNoMore() {
- view.onHideLoading();
- view.onShowNoMore();
- }
- }
4.2.一个构造函数。
传进去一个底层接口中定义的一个View。
保存这个View,以后再用。
4.3.重写doLoadData函数。
传进去一个String...类型,类似于数组。
然后调用API请求。
4.4.重写加载更多doLoadMoreData函数。
偏移量增加20即可。
然后再调用doLoadData函数。
4.5.重写设置适配器doSetAdapter函数。
传进去一个List。
然后调用视图层的onSetAdapter函数。
然后调用试图层的onHideLoading函数。
4.6.重写刷新。
将List清空,设置偏移量为0。
然后调用doLoadData。
4.7.重写网络错误。
调用视图层的隐藏加载函数。
调用视图层的显示网络错误。
4.8.重写没有更多。
调用视图层的隐藏加载函数。
调用视图层的显示没有更多函数。
5.注册数据类型
5.1.首先在新闻评论片段中给适配器添加数据类型
- adapter = new MultiTypeAdapter(oldItems);
- Register.registerNewsCommentItem(adapter);
- recyclerView.setAdapter(adapter);
5.2.然后在自定义类Register统一注册这个页面需要的类型
- public static void registerNewsCommentItem(@NonNull MultiTypeAdapter adapter) {
- adapter.register(NewsCommentBean.DataBean.CommentBean.class, new NewsCommentViewBinder());
- adapter.register(LoadingBean.class, new LoadingViewBinder());
- adapter.register(LoadingEndBean.class, new LoadingEndViewBinder());
- }
5.3.然后看一下这个新闻评论的视图绑定类==>NewsCommentViewBinder
- package com.jasonjan.headnews.binder.news;
- import android.content.ClipData;
- import android.content.ClipboardManager;
- import android.content.Context;
- import android.support.annotation.NonNull;
- import android.support.design.widget.Snackbar;
- import android.support.v7.widget.RecyclerView;
- import android.view.LayoutInflater;
- import android.view.View;
- import android.view.ViewGroup;
- import android.widget.ImageView;
- import android.widget.TextView;
- import com.jasonjan.headnews.R;
- import com.jasonjan.headnews.bean.news.NewsCommentBean;
- import com.jasonjan.headnews.main.ErrorAction;
- import com.jasonjan.headnews.main.IntentAction;
- import com.jasonjan.headnews.module.base.BaseActivity;
- import com.jasonjan.headnews.util.ImageLoader;
- import com.jasonjan.headnews.widget.BottomSheetDialogFixed;
- import me.drakeet.multitype.ItemViewBinder;
- /**
- * Created by JasonJan on 2018/1/9.
- */
- public class NewsCommentViewBinder extends ItemViewBinder<NewsCommentBean.DataBean.CommentBean,NewsCommentViewBinder.ViewHolder> {
- @NonNull
- @Override
- protected NewsCommentViewBinder.ViewHolder onCreateViewHolder(@NonNull LayoutInflater inflater, @NonNull ViewGroup parent) {
- View view = inflater.inflate(R.layout.item_news_comment, parent, false);
- return new ViewHolder(view);
- }
- @Override
- protected void onBindViewHolder(@NonNull final ViewHolder holder, @NonNull final NewsCommentBean.DataBean.CommentBean item) {
- final Context context = holder.itemView.getContext();
- try {
- String iv_avatar = item.getUser_profile_image_url();
- String tv_username = item.getUser_name();
- String tv_text = item.getText();
- int tv_likes = item.getDigg_count();
- ImageLoader.loadCenterCrop(context, iv_avatar, holder.iv_avatar, R.color.viewBackground);
- holder.tv_username.setText(tv_username);
- holder.tv_text.setText(tv_text);
- holder.tv_likes.setText(tv_likes + "赞");
- holder.itemView.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- final String content = item.getText();
- final BottomSheetDialogFixed dialog = new BottomSheetDialogFixed(context);
- dialog.setOwnerActivity((BaseActivity) context);
- View view = ((BaseActivity) context).getLayoutInflater().inflate(R.layout.item_comment_action_sheet, null);
- view.findViewById(R.id.layout_copy_text).setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- ClipboardManager copy = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
- ClipData clipData = ClipData.newPlainText("text", content);
- copy.setPrimaryClip(clipData);
- Snackbar.make(holder.itemView, R.string.copied_to_clipboard, Snackbar.LENGTH_SHORT).show();
- dialog.dismiss();
- }
- });
- view.findViewById(R.id.layout_share_text).setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- IntentAction.send(context, content);
- dialog.dismiss();
- }
- });
- dialog.setContentView(view);
- dialog.show();
- }
- });
- } catch (Exception e) {
- ErrorAction.print(e);
- }
- }
- public class ViewHolder extends RecyclerView.ViewHolder {
- private ImageView iv_avatar;
- private TextView tv_username;
- private TextView tv_text;
- private TextView tv_likes;
- public ViewHolder(View itemView) {
- super(itemView);
- this.iv_avatar = itemView.findViewById(R.id.iv_avatar);
- this.tv_username = itemView.findViewById(R.id.tv_username);
- this.tv_text = itemView.findViewById(R.id.tv_text);
- this.tv_likes = itemView.findViewById(R.id.tv_likes);
- }
- }
- }
5.4.需要一个新闻评论每一个item的布局==>item_news_comment.xml
- <?xml version="1.0" encoding="utf-8"?>
- <RelativeLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:background="@color/viewBackground">
- <LinearLayout
- android:id="@+id/content"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:background="?attr/selectableItemBackground"
- android:foreground="?attr/selectableItemBackground"
- android:orientation="vertical"
- android:paddingBottom="8dp"
- android:paddingLeft="16dp"
- android:paddingRight="16dp"
- android:paddingTop="8dp">
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="horizontal">
- <com.meiji.toutiao.widget.CircleImageView
- android:id="@+id/iv_avatar"
- android:layout_width="22dp"
- android:layout_height="22dp"
- android:layout_gravity="center"/>
- <TextView
- android:id="@+id/tv_username"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- android:layout_marginLeft="8dp"
- android:layout_marginStart="8dp"
- android:ellipsize="end"
- android:maxLines="1"
- tools:text="小恢恢的帽子"/>
- </LinearLayout>
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginTop="4dp"
- android:orientation="vertical">
- <TextView
- android:id="@+id/tv_text"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- tools:text="光看个开头就笑的不行了,咱们中国有个传统,就是家里来客人了,要到门口迎一下,如果手里还带着礼物,那要先接过来,因为人家大老远一路带过来的,已经很累了,更何况老美不远万里带过来的呢,如果不接过来那也太不像话了,会让国际笑话中国,也有失大国风范!这也是一种礼貌,更是中华民族的传统美德!"/>
- <TextView
- android:id="@+id/tv_likes"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginTop="2dp"
- android:gravity="end"
- android:maxLines="1"
- tools:text="4832赞"/>
- </LinearLayout>
- </LinearLayout>
- <View
- android:id="@+id/divider"
- android:layout_width="match_parent"
- android:layout_height="1px"
- android:layout_below="@+id/content"
- android:background="@color/line_divider"/>
- </RelativeLayout>
预览页面:
6.API请求
6.1.在IMobieNewsApi中写这个函数
- /**
- * 获取新闻评论
- * 按热度排序
- * http://is.snssdk.com/article/v53/tab_comments/?group_id=6314103921648926977&offset=0&tab_index=0
- * 按时间排序
- * http://is.snssdk.com/article/v53/tab_comments/?group_id=6314103921648926977&offset=0&tab_index=1
- *
- * @param groupId 新闻ID
- * @param offset 偏移量
- */
- @GET("http://is.snssdk.com/article/v53/tab_comments/")
- Observable<NewsCommentBean> getNewsComment(
- @Query("group_id") String groupId,
- @Query("offset") int offset);
传递进来两个参数,一个是新闻Id,一个是偏移量(就是获取那些评论)。
传出去Observable<NewsCommentBean>
6.2.调用方式==>在处理器的加载数据中执行
- RetrofitFactory.getRetrofit().create(IMobileNewsApi.class)
- .getNewsComment(groupId, offset)
- .subscribeOn(Schedulers.io())
- .map(new Function<NewsCommentBean, List<NewsCommentBean.DataBean.CommentBean>>() {
- @Override
- public List<NewsCommentBean.DataBean.CommentBean> apply(@NonNull NewsCommentBean newsCommentBean) throws Exception {
- List<NewsCommentBean.DataBean.CommentBean> data = new ArrayList<>();
- for (NewsCommentBean.DataBean bean : newsCommentBean.getData()) {
- data.add(bean.getComment());
- }
- return data;
- }
- })
- .compose(view.<List<NewsCommentBean.DataBean.CommentBean>>bindToLife())
- .observeOn(AndroidSchedulers.mainThread())
- .subscribe(new Consumer<List<NewsCommentBean.DataBean.CommentBean>>() {
- @Override
- public void accept(@NonNull List<NewsCommentBean.DataBean.CommentBean> list) throws Exception {
- if (null != list && list.size() > 0) {
- doSetAdapter(list);
- } else {
- doShowNoMore();
- }
- }
- }, new Consumer<Throwable>() {
- @Override
- public void accept(@NonNull Throwable throwable) throws Exception {
- doShowNetError();
- ErrorAction.print(throwable);
- }
- });
- }
TouTiao开源项目 分析笔记16 新闻评论的更多相关文章
- TouTiao开源项目 分析笔记15 新闻详情之两种类型的实现
1.预览效果 1.1.首先看一下需要实现的效果. 第一种,文字类型新闻. 第二种,图片类型新闻. 1.2.在NewsArticleTextViewBinder中设置了点击事件 RxView.click ...
- TouTiao开源项目 分析笔记17 新闻媒体专栏
1.效果预览 1.1.要实现的效果 1.2.如何调转到新闻媒体专栏 点击右上角的用户图标. 在新闻详情页面的Fragment的菜单点击事件中触发. case R.id.action_open_medi ...
- TouTiao开源项目 分析笔记14 段子评论
1.段子页面详情 1.1.先看看预览界面吧 左边的页面已经实现了,现在的目的就是要实现点击左侧的每一个item 然后跳转到右边相应的段子详情页面. 1.2.首先肯定有右侧这个活动==>JokeC ...
- TouTiao开源项目 分析笔记2
1.Constant常量定义类 1.1.源代码 public class Constant { public static final String USER_AGENT_MOBILE = " ...
- TouTiao开源项目 分析笔记12 从总体到局部 构建视频主页面
1.构建视频主列表的整体碎片VideoTabLayout 1.1.首先创建一个VideoTabLayout package com.jasonjan.headnews.module.video; im ...
- TouTiao开源项目 分析笔记18 视频详情页面
1.效果预览 1.1.需要做到的真实效果 1.2.触发的点击事件 在MediaArticleVideoViewBinder的每一个item点击事件中: VideoContentActivity.lau ...
- TouTiao开源项目 分析笔记10 实现通用普通文章片段页面
1.RxJava的Observable数据操作符总结 1.1.Map操作符 Map操作符对原始Observable发射的没一项数据应用一个你选择的函数, 然后返回一个发射这些结果的Observable ...
- TouTiao开源项目 分析笔记20 问答详情
1.效果预览 1.1.效果预览,从问答列表开始 前面实现了从列表到内容. 这里主要讲解从内容到详情. 点击每一个回答内容,进入回答详情页面. 1.2.触发的点击事件 在WendaContentView ...
- TouTiao开源项目 分析笔记6
1.NewsChannelBean简单类笔记 1.1.Comparable接口的实现和使用 参考文章:Comparable接口的实现和使用. 因为NewsChannelBean实现了Comparabl ...
随机推荐
- sharepoint2007就地升级2010系列(二)环境概述及升级前准备
环境介绍:1台2GB的虚机 现在是windows server 2008 sp2 X64 +SQL 2005+SQL2005 sp3+sharepoint2007+sharepoint2007SP2 ...
- Azure进阶攻略丨如何驾驭罢工的Linux虚机网卡?
很多人的生活中,流传着一个屡试不爽,据说可以解决任何问题的百宝锦囊: 所以经常可以听到类似这样的对话: -我的电脑咋上不去网了? -重启一下电脑. -还是不行呢! -重启一下路由器. -怎么还不行-_ ...
- python3绘图示例2(基于matplotlib:柱状图、分布图、三角图等)
#!/usr/bin/env python# -*- coding:utf-8 -*- from matplotlib import pyplot as pltimport numpy as npim ...
- ALPS语言学校(西雅图)|ALPS Language School (Seattle)
http://www.swliuxue.com/school-3879.html 所属国家: 美国 所在省洲: 华盛顿州 所在城市: 华盛顿州 建校时间: 1992年 学校类型: 院校 学校类别: 私 ...
- TP5.1:facade静态代理
THINKPHP中有很多很多的facade静态代理,这些静态代理的位置在:thinkphp\think\facade文件夹下 1.在app\commom中新建一个文件,名为:Test.php,表示被代 ...
- C++指针、引用、const
; int *p = &a; //定义指针p指向变量a *p = ; //*p代表a的值 ; p = &b; //p指向变量b *p = ; //此时*p代表b的值 ] = {,,}; ...
- Django Field lookups (字段查找)
字段查找是指定SQL WHERE子句的核心内容的方式. 它们被指定为QuerySet方法filter().exclude()和get()的关键字参数. 1.exact:精确查找.如果为比较提供的值为N ...
- IOS 设置定时器,执行方法
//设置定时器(1秒后跳到一下题) [self performSelector:@selector(nextQuestion) withObject:nil afterDelay:1.0];
- 转:adb操作命令详解及大全
说到 ADB 大家应该都不陌生,即 Android Debug Bridge,Android调试桥,身为 Android 开发的我们,熟练使用 ADB 命令将会大大提升我们的开发效率, ADB 的命令 ...
- CentOS安装配置MongoDB
1.下载安装包: wget http://fastdl.mongodb.org/linux/mongodb-linux-i686-2.0.3.tgz 2.解压: tar -zxvf mongodb-l ...