swipebacklayout的使用,处理TextView中图片的显示以及类360滚动布局

AlyciaGagne 9年前

来自: http://blog.csdn.net//chenguang79/article/details/50508629


     今天我们来完成,点击信息,进入到详细的信息页面。我们先根据下面的图,来分析一下我们要如何布局,如何实现。

    

       首先,我们看到,在这个详细页面的title中,文字是这个信息的标题,其中有一个共享按钮的功能,可以将信息共享到其它程序中,还有一个更多,里面,有几个功能,其中主要的就是修改文字的大小。下面,就是一个正常的信息显示,大家注意,这个信息显示有一个特点,就是在兰色的title下面和作者信息之间的标题,如果,我向上推动信息,看下面更多的内容,你会发现,这个标题会向上移动,直到消息,然后,作者的信息这行,到了顶部就不动了,而下面的正文部分,开始滚动。

       其次,我们看到下面的工具栏,你在向上移动正文的时候,他会隐藏,而向下的时候,它会再显示出来。

      接着,在正文的部分,会有图片显示出来,因为我采用的是将网上图片下载到本地进行加载,为了不在模拟器中产生大量图片,我就把这个功能关了,在本文的最后,我会将此功能打开,再切一个图看一下。

      最后,你会发现,我们各右滑动屏幕的时候,这个页面各右移动,然后关掉。

      好了,我们先从第一个问题开始解决,这个页面的title不用多说了,就是采用我们原来的说过的Toolbar来处理,没有什么可说的,唯一一点说明就是这个共享功能,这个系统给我们提供了一个现成的,只要加上应的样式就会出来,可是这个图标的大小,却与别的图标不一样,大了很多,这个我一直没有解决,哪位兄弟解决了,麻烦告诉我一下。

      下面的布局,就有意思了,它有点像360里面的功能一样,最上面的title会被隐藏,而中间的部分到了顶部就不动了,而正文会开始滚动,这个功能我想了很久,没想到什么好的方法,后来看了网上几位大神的blog才明白,这个只能是自定义布局开发。这里采用的是http://blog.csdn.net/lmj623565791/article/details/43649913此博客的代码,只是简单的改了一点,思路什么的,大家可以通过此博客去了解。

       那么最后一个问题,就是下面的工具栏,会显示和隐藏,我们会看到,它会在正文的上面显示出来,这样我们就采用一个FrameLayout做为主布局,然后把下面的工具栏放在上面,用程序来控制它的显示与隐藏。好了,思路是这样,我们开始代码:

       我们先把自定义布局的代码写出来,这个是根据上面我给出的blog代码,简单改了一点StickyNavLayout.java

      

import android.content.Context;  import android.util.AttributeSet;  import android.util.Log;  import android.view.MotionEvent;  import android.view.VelocityTracker;  import android.view.View;  import android.view.ViewConfiguration;  import android.view.ViewGroup;  import android.widget.LinearLayout;  import android.widget.ListView;  import android.widget.OverScroller;  import android.widget.ScrollView;    import com.example.cg.zhihu_one.R;      /**   * Created by cg on 2015/8/18.   */  public class StickyNavLayout extends LinearLayout {      private View mTop;      private View mNav;      private LinearLayout mViewPager;        private int mTopViewHeight;      private ViewGroup mInnerScrollView;      private boolean isTopHidden = false;        private OverScroller mScroller;      private VelocityTracker mVelocityTracker;      private int mTouchSlop;      private int mMaximumVelocity, mMinimumVelocity;        private float mLastY;      private boolean mDragging;        private boolean isInControl = false;        public StickyNavLayout(Context context, AttributeSet attrs) {          super(context, attrs);          setOrientation(LinearLayout.VERTICAL);            mScroller = new OverScroller(context);          mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();          mMaximumVelocity = ViewConfiguration.get(context)                  .getScaledMaximumFlingVelocity();          mMinimumVelocity = ViewConfiguration.get(context)                  .getScaledMinimumFlingVelocity();        }        @Override      protected void onFinishInflate() {          super.onFinishInflate();          mTop = findViewById(R.id.id_stickynavlayout_topview);          mNav = findViewById(R.id.id_stickynavlayout_indicator);          View view = findViewById(R.id.id_stickynavlayout_viewpager);          if (!(view instanceof LinearLayout)) {              throw new RuntimeException(                      "id_stickynavlayout_viewpager show used by ViewPager !");          }          mViewPager = (LinearLayout) view;            //此处直接给出下面的滚动条的布局          //mInnerScrollView = (ViewGroup)findViewById(R.id.scorl_main);      }        @Override      protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {          super.onMeasure(widthMeasureSpec, heightMeasureSpec);          ViewGroup.LayoutParams params = mViewPager.getLayoutParams();          params.height = getMeasuredHeight() - mNav.getMeasuredHeight();        }        @Override      protected void onSizeChanged(int w, int h, int oldw, int oldh) {          super.onSizeChanged(w, h, oldw, oldh);          mTopViewHeight = mTop.getMeasuredHeight();      }        @Override      public boolean dispatchTouchEvent(MotionEvent ev) {          int action = ev.getAction();          float y = ev.getY();            switch (action) {              case MotionEvent.ACTION_DOWN:                  mLastY = y;                  break;              case MotionEvent.ACTION_MOVE:                  float dy = y - mLastY;                  getCurrentScrollView();                    if (mInnerScrollView instanceof ScrollView) {                      if (mInnerScrollView.getScrollY() == 0 && isTopHidden && dy > 0                              && !isInControl) {                          isInControl = true;                          ev.setAction(MotionEvent.ACTION_CANCEL);                          MotionEvent ev2 = MotionEvent.obtain(ev);                          dispatchTouchEvent(ev);                          ev2.setAction(MotionEvent.ACTION_DOWN);                          return dispatchTouchEvent(ev2);                      }                  } else if (mInnerScrollView instanceof ListView) {                        ListView lv = (ListView) mInnerScrollView;                      View c = lv.getChildAt(lv.getFirstVisiblePosition());                        if (!isInControl && c != null && c.getTop() == 0 && isTopHidden                              && dy > 0) {                          isInControl = true;                          ev.setAction(MotionEvent.ACTION_CANCEL);                          MotionEvent ev2 = MotionEvent.obtain(ev);                          dispatchTouchEvent(ev);                          ev2.setAction(MotionEvent.ACTION_DOWN);                          return dispatchTouchEvent(ev2);                      }                  }                  break;          }          return super.dispatchTouchEvent(ev);      }        /**       *       */      @Override      public boolean onInterceptTouchEvent(MotionEvent ev) {          final int action = ev.getAction();          float y = ev.getY();          switch (action) {              case MotionEvent.ACTION_DOWN:                  mLastY = y;                  break;              case MotionEvent.ACTION_MOVE:                  float dy = y - mLastY;                  getCurrentScrollView();                  if (Math.abs(dy) > mTouchSlop) {                      mDragging = true;                      if (mInnerScrollView instanceof ScrollView) {                          // 如果topView没有隐藏                          // 或sc的scrollY = 0 && topView隐藏 && 下拉,则拦截                          if (!isTopHidden                                  || (mInnerScrollView.getScrollY() == 0                                  && isTopHidden && dy > 0)) {                                initVelocityTrackerIfNotExists();                              mVelocityTracker.addMovement(ev);                              mLastY = y;                              return true;                          }                      } else if (mInnerScrollView instanceof ListView) {                            ListView lv = (ListView) mInnerScrollView;                          View c = lv.getChildAt(lv.getFirstVisiblePosition());                          // 如果topView没有隐藏                          // 或sc的listView在顶部 && topView隐藏 && 下拉,则拦截                            if (!isTopHidden || //                                  (c != null //                                          && c.getTop() == 0//                                          && isTopHidden && dy > 0)) {                                initVelocityTrackerIfNotExists();                              mVelocityTracker.addMovement(ev);                              mLastY = y;                              return true;                          }                      }                    }                  break;              case MotionEvent.ACTION_CANCEL:              case MotionEvent.ACTION_UP:                  mDragging = false;                  recycleVelocityTracker();                  break;          }          return super.onInterceptTouchEvent(ev);      }        private void getCurrentScrollView() {            //此处因为下面是滚动条,所以将viewpager隐掉          /*int currentItem = mViewPager.getCurrentItem();          PagerAdapter a = mViewPager.getAdapter();          if (a instanceof FragmentPagerAdapter) {              FragmentPagerAdapter fadapter = (FragmentPagerAdapter) a;              Fragment item = (Fragment) fadapter.instantiateItem(mViewPager,                      currentItem);              mInnerScrollView = (ViewGroup) (item.getView()                      .findViewById(R.id.id_stickynavlayout_innerscrollview));          } else if (a instanceof FragmentStatePagerAdapter) {              FragmentStatePagerAdapter fsAdapter = (FragmentStatePagerAdapter) a;              Fragment item = (Fragment) fsAdapter.instantiateItem(mViewPager,                      currentItem);              mInnerScrollView = (ViewGroup) (item.getView()                      .findViewById(R.id.id_stickynavlayout_innerscrollview));          }*/        }        @Override      public boolean onTouchEvent(MotionEvent event) {          initVelocityTrackerIfNotExists();          mVelocityTracker.addMovement(event);          int action = event.getAction();          float y = event.getY();            switch (action) {              case MotionEvent.ACTION_DOWN:                  if (!mScroller.isFinished())                      mScroller.abortAnimation();                  mLastY = y;                  return true;              case MotionEvent.ACTION_MOVE:                  float dy = y - mLastY;                    Log.e("TAG", "dy = " + dy + " , y = " + y + " , mLastY = " + mLastY);                    if (!mDragging && Math.abs(dy) > mTouchSlop) {                      mDragging = true;                  }                  if (mDragging) {                      scrollBy(0, (int) -dy);                        // 如果topView隐藏,且上滑动时,则改变当前事件为ACTION_DOWN                      if (getScrollY() == mTopViewHeight && dy < 0) {                          event.setAction(MotionEvent.ACTION_DOWN);                          dispatchTouchEvent(event);                          isInControl = false;                      }                  }                    mLastY = y;                  break;              case MotionEvent.ACTION_CANCEL:                  mDragging = false;                  recycleVelocityTracker();                  if (!mScroller.isFinished()) {                      mScroller.abortAnimation();                  }                  break;              case MotionEvent.ACTION_UP:                  mDragging = false;                  mVelocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);                  int velocityY = (int) mVelocityTracker.getYVelocity();                  if (Math.abs(velocityY) > mMinimumVelocity) {                      fling(-velocityY);                  }                  recycleVelocityTracker();                  break;          }            return super.onTouchEvent(event);      }        public void fling(int velocityY) {          mScroller.fling(0, getScrollY(), 0, velocityY, 0, 0, 0, mTopViewHeight);          invalidate();      }        @Override      public void scrollTo(int x, int y) {          if (y < 0) {              y = 0;          }          if (y > mTopViewHeight) {              y = mTopViewHeight;          }          if (y != getScrollY()) {              super.scrollTo(x, y);          }            isTopHidden = getScrollY() == mTopViewHeight;        }        @Override      public void computeScroll() {          if (mScroller.computeScrollOffset()) {              scrollTo(0, mScroller.getCurrY());              invalidate();          }      }        private void initVelocityTrackerIfNotExists() {          if (mVelocityTracker == null) {              mVelocityTracker = VelocityTracker.obtain();          }      }        private void recycleVelocityTracker() {          if (mVelocityTracker != null) {              mVelocityTracker.recycle();              mVelocityTracker = null;          }      }    }

     好,我们来看一下主程序与布局
     activity_index_detail.xml
    
<FrameLayout      xmlns:android="http://schemas.android.com/apk/res/android"      android:layout_width="match_parent"      android:layout_height="match_parent">      <LinearLayout          android:layout_width="fill_parent"          android:layout_height="fill_parent"          android:orientation="vertical">          <include              layout="@layout/toolbar" />            <com.example.cg. zhihu_one.untils.StickyNavLayout              android:layout_width="match_parent"              android:layout_height="match_parent"              android:orientation="vertical">                <LinearLayout                  android:id="@id/id_stickynavlayout_topview"                  android:layout_width="fill_parent"                  android:layout_height="wrap_content"                  android:background="#C1C1C1" >                    <TextView                      android:id="@+id/txt_index_detail_title"                      android:layout_width="fill_parent"                      android:layout_height="wrap_content"                      android:text=""                      android:textColor="#454545"                      android:textSize="@dimen/list_remark_size"                      android:layout_marginTop="6dp"                      android:layout_marginBottom="6dp"                      android:layout_marginLeft="5dp"                      android:layout_marginRight="2dp"                      />              </LinearLayout>                <LinearLayout                  android:id="@+id/id_stickynavlayout_indicator"                  android:layout_width="fill_parent"                  android:layout_height="wrap_content"                  android:orientation="horizontal">                  <com.android.volley.toolbox.NetworkImageView                      android:id="@+id/netimg_index_detail_userpic"                      android:layout_width="0dp"                      android:layout_height="50dp"                      android:layout_weight="1"                      android:src="@drawable/img_empty_followers"                      android:layout_marginTop="5dp"                      android:layout_marginLeft="5dp"                      android:layout_marginBottom="5dp"                      />                  <LinearLayout                      android:layout_width="0dp"                      android:layout_height="wrap_content"                      android:orientation="vertical"                      android:layout_weight="4">                      <TextView                          android:id="@+id/txt_index_detail_userName"                          android:layout_width="wrap_content"                          android:layout_height="wrap_content"                          android:textColor="@color/black"                          android:textSize="@dimen/list_remark_size"                          android:layout_marginTop="5dp"/>                      <TextView                          android:id="@+id/txt_index_detail_userRemark"                          android:layout_width="wrap_content"                          android:layout_height="wrap_content"                          android:textColor="@color/gray"                          android:textSize="@dimen/list_remark_size"                          android:layout_marginTop="2dp"                          android:layout_marginBottom="5dp"                          android:lines="1"/>                    </LinearLayout>                    <LinearLayout                      android:id="@+id/linear_index_detail_zan"                      android:layout_width="0dp"                      android:layout_height="fill_parent"                      android:layout_weight="2"                      android:orientation="horizontal"                      android:layout_gravity="center_vertical"                      android:gravity="center"                      android:clickable="true">                      <View                          android:layout_width="1dip"                          android:layout_height="15dp"                          android:background="@color/gray"                          android:layout_gravity="center_vertical"                          />                      <ImageView                          android:id="@+id/img_index_detail_zan"                          android:layout_width="wrap_content"                          android:layout_height="wrap_content"                          android:src="@drawable/ic_vote_normal"                          android:layout_marginLeft="10dp"/>                      <TextView                          android:id="@+id/txt_index_detail_zanNum"                          android:layout_width="wrap_content"                          android:layout_height="wrap_content"                          android:text="120"                          android:layout_marginLeft="10dp"                          android:textColor="@color/gray"/>                    </LinearLayout>              </LinearLayout>                <View                  android:layout_width="fill_parent"                  android:layout_height="1dp"                  android:background="#CCCCCC" />                  <LinearLayout                  android:id="@id/id_stickynavlayout_viewpager"                  android:layout_width="match_parent"                  android:layout_height="match_parent"                  android:layout_marginLeft="5dp"                  android:layout_marginRight="2dp">                    <ScrollView                      android:id="@+id/scorl_main"                      android:layout_width="fill_parent"                      android:layout_height="fill_parent">                          <TextView                          android:id="@+id/txt_index_detail_content"                          android:layout_width="wrap_content"                          android:layout_height="wrap_content"                          android:clickable="true"                          />                        </ScrollView>                  </LinearLayout>              </com.example.cg.zhihu_one.untils.StickyNavLayout>      </LinearLayout>      <LinearLayout          android:id="@+id/linear_index_detail_seekbar"          android:layout_width="fill_parent"          android:layout_height="50dp"          android:orientation="horizontal"          android:background="#D4D4D4"          android:layout_gravity="bottom"          android:gravity="center">          <TextView              android:text="@string/index_detail_TextSize_small"              android:layout_width="0dp"              android:layout_height="wrap_content"              android:layout_weight="1"              android:gravity="center"/>          <SeekBar              android:id="@+id/seekbar_index_detail"              android:layout_width="0dp"              android:layout_height="wrap_content"              android:layout_weight="5"              android:max="5"              />          <TextView              android:text="@string/index_detail_TextSize_big"              android:layout_width="0dp"              android:layout_height="wrap_content"              android:layout_weight="1"              android:gravity="center"/>      </LinearLayout>      <LinearLayout          android:id="@id/linear_index_detail_bottomtitle"          android:layout_width="fill_parent"          android:layout_height="50dp"          android:background="#D4D4D4"          android:layout_gravity="bottom">          <TextView              android:id="@+id/txt_index_detail_help"              android:layout_width="0dp"              android:layout_height="50dp"              android:layout_weight="1"              android:text="@string/index_detail_help"              android:clickable="true"              android:gravity="center"              android:layout_marginTop="5dp"              android:drawableTop="@drawable/ic_nohelp"/>          <TextView              android:id="@+id/txt_index_detail_thank"              android:layout_width="0dp"              android:layout_height="50dp"              android:layout_weight="1"              android:layout_marginTop="5dp"              android:text="@string/index_detail_thank"              android:clickable="true"              android:gravity="center"              android:drawableTop="@drawable/ic_thank"/>          <TextView              android:id="@+id/txt_index_detail_Collection"              android:layout_width="0dp"              android:layout_height="50dp"              android:layout_weight="1"              android:layout_marginTop="5dp"              android:text="@string/index_detail_collection"              android:clickable="true"              android:gravity="center"              android:drawableTop="@drawable/ic_collect"/>          <TextView              android:id="@+id/txt_index_detail_Comment"              android:layout_width="0dp"              android:layout_height="50dp"              android:layout_weight="1"              android:layout_marginTop="5dp"              android:text="@string/index_detail_comment"              android:clickable="true"              android:gravity="center"              android:drawableTop="@drawable/ic_comment"/>      </LinearLayout>    </FrameLayout>

        注意:这里在StickyNavLayout布局里,好几个控件我们不是定义它的id,而是给它赋予id,这是为什么呢, 主要是为了自定义布局里面好取值,这里我们在values中定义了一个ids_sticky_nav_Llayout.xml文件

        <?xml version="1.0" encoding="utf-8"?>
           <resources>
               <item name="id_stickynavlayout_topview" type="id"/>
              <item name="id_stickynavlayout_viewpager" type="id"/>
              <item name="id_stickynavlayout_indicator" type="id"/>
              <item name="id_stickynavlayout_innerscrollview" type="id"/>
              <item name="linear_index_detail_bottomtitle" type="id"/>
          </resources>
      当然了,为了以后改文字和通用性比较好, 我在values文件夹的strings.xml文件里,定义了一些文字

      strings.xml

     

<resources>      <string name="app_name">zhihu_one</string>        <string name="hello_world">Hello world!</string>      <string name="action_settings">Settings</string>        <string name="drawer_open">打开</string>      <string name="drawer_close">关闭</string>        <string name="menu_index">首页</string>      <string name="menu_search">查询</string>      <string name="menu_notify">通知</string>      <string name="menu_about">关于</string>      <string name="menu_register">登出</string>      <string name="menu_share">分享</string>      <string name="menu_shuffle">随机看</string>      <string name="title_activity_index_detail">Index_detailActivity</string>        <string name="index_detail_TextSize_small">小</string>      <string name="index_detail_TextSize_big">大</string>      <string name="index_detail_help">没有帮助</string>      <string name="index_detail_nohelp">撤消没有帮助</string>      <string name="index_detail_thank">感谢</string>      <string name="index_detail_thanked">已感谢</string>      <string name="index_detail_collection">收藏</string>      <string name="index_detail_collectioned">已收藏</string>      <string name="index_detail_comment">评论 0</string>  </resources>

     好,这时候,我们在原来的代码中,Index_lv_Adapter.java中,将点击事件中的跳转的代码加上,如下

   

listclass.linear_index_item_content.setOnClickListener(new View.OnClickListener() {              @Override              public void onClick(View v) {                  Intent cIntent = new Intent();                  cIntent.setClass(context, Index_detailActivity.class);                  cIntent.putExtra("questionID", list_index.get(position).getQuestionID());                  cIntent.putExtra("questionTitle",list_index.get(position).getQuestionTitle());                  context.startActivity(cIntent);              }          });
     这里有一点,你会问了,我传一个id过去不就完了吗,因为我的数据全是根据id,然后从服务器里传回来的,为什么还要再专一个title呢。这个在后面,你就明白了。好了,我们来看Index_detailActivity.java的代码。
     还记得我们的最后一个问题,就是向右滑动手机,这个Activity会向左移动然后关闭,这个呢,我们使用的是网上第三方插件,叫SwipeBackLayout,官方地址:https://github.com/ikew0ng/SwipeBackLayout。在我们android studio开发工具中,只要引入
compile 'me.imid.swipebacklayout.lib:library:1.0.0'即可。这里要注意一点啊。原生代码继承的是Activity可是我们这里使用了Toolbar哪么我们就得改写一下,让他继承ActionBarActivity,我们重新建一个类叫SwipeBackToolBarActivity,代码如下:

    import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.View;

import me.imid.swipebacklayout.lib.SwipeBackLayout;
import me.imid.swipebacklayout.lib.app.SwipeBackActivityBase;
import me.imid.swipebacklayout.lib.app.SwipeBackActivityHelper;

/**
* Created by cg on 2015/11/10.
*/
public class SwipeBackToolBarActivity extends ActionBarActivity implements SwipeBackActivityBase {
private SwipeBackActivityHelper mHelper;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mHelper = new SwipeBackActivityHelper(this);
mHelper.onActivityCreate();
}

@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
mHelper.onPostCreate();
}

@Override
public View findViewById(int id) {
View v = super.findViewById(id);
if (v == null && mHelper != null)
return mHelper.findViewById(id);
return v;
}

@Override
public SwipeBackLayout getSwipeBackLayout() {
return mHelper.getSwipeBackLayout();
}
@Override
public void setSwipeBackEnable(boolean enable) {
getSwipeBackLayout().setEnableGesture(enable);
}

@Override
public void scrollToFinishActivity() {
getSwipeBackLayout().scrollToFinishActivity();
}
}
       我们先让我们的主程序继承这个类SwipeBackToolBarActivity。代码如下:

      

import android.app.ProgressDialog;  import android.os.Bundle;  import android.support.v7.widget.Toolbar;  import android.view.Menu;  import android.view.MenuItem;  import android.view.View;  import android.widget.ImageView;  import android.widget.LinearLayout;  import android.widget.ScrollView;  import android.widget.TextView;    import com.android.volley.toolbox.NetworkImageView;  import com.example.cg.zhihu_one.untils.SwipeBackToolBarActivity;    import me.imid.swipebacklayout.lib.SwipeBackLayout;    public class Index_detailActivity extends SwipeBackToolBarActivity implements View.OnClickListener {        private SwipeBackLayout mSwipeBackLayout;                           //定义侧滑退出此activity      private Toolbar toolbar;                                            //定义toolbar        private int qid;                                                    //定义接到的问题id      private String questionTitle;                                       //定义问题的标题        private ProgressDialog myProgressDialog;                            //定义信息等等控件        private TextView txt_index_detail_title;                            //定义问题的标题      private NetworkImageView netimg_index_detail_userpic;               //定义用户头像      private TextView txt_index_detail_userName;                         //定义用户名字      private TextView txt_index_detail_userRemark;                       //定义用户简介      private ImageView img_index_detail_zan;                             //定义点赞的图标      private TextView txt_index_detail_zanNum;                           //定义点赞数      private ScrollView scorl_main;                                      //内容滚动条      private TextView txt_index_detail_content;                          //定义内容      private LinearLayout linear_index_detail_bottomtitle;               //定义底部工具栏      private LinearLayout id_stickynavlayout_indicator;        @Override      protected void onCreate(Bundle savedInstanceState) {          super.onCreate(savedInstanceState);          setContentView(R.layout.activity_index_detail);            qid = getIntent().getIntExtra("questionID", 0);              //从列表页,接收问题的id          questionTitle = getIntent().getStringExtra("questionTitle"); //接收到的标题            mSwipeBackLayout = getSwipeBackLayout();          int edgeFlag = SwipeBackLayout.EDGE_LEFT;       //从右向左滑动          //int edgeFlag = SwipeBackLayout.EDGE_RIGHT;      //从左向右滑动          //int edgeFlag = SwipeBackLayout.EDGE_BOTTOM;     //从下向上滑动          //int edgeFlag = SwipeBackLayout.EDGE_ALL;          //从右,右,下都可以滑动          mSwipeBackLayout.setEdgeTrackingEnabled(edgeFlag);                    toolbar = (Toolbar)this.findViewById(R.id.toolbar);          toolbar.setTitle(questionTitle);                     // 标题的文字需在setSupportActionBar之前,不然会无效          setSupportActionBar(toolbar);              initControls();      }        /**       * 初始化各控件       */      private void initControls() {          txt_index_detail_title = (TextView)findViewById(R.id.txt_index_detail_title);          //注意这里,我们把标题的内容给TextView赋值,是为了能让我们自定义的StickNavLayout布局去算一下,它的高度。          //因为我们的数据值是通过异步从远程服务器中得到了,如果现在不给值,会有一个时间差,会造成计算高度有误          txt_index_detail_title.setText(questionTitle);          netimg_index_detail_userpic = (NetworkImageView)findViewById(R.id.netimg_index_detail_userpic);          txt_index_detail_userName = (TextView)findViewById(R.id.txt_index_detail_userName);          txt_index_detail_userRemark = (TextView)findViewById(R.id.txt_index_detail_userRemark);          txt_index_detail_zanNum = (TextView)findViewById(R.id.txt_index_detail_zanNum);          txt_index_detail_content = (TextView)findViewById(R.id.txt_index_detail_content);          txt_index_detail_content.setOnClickListener(this);          linear_index_detail_bottomtitle = (LinearLayout)findViewById(R.id.linear_index_detail_bottomtitle);          id_stickynavlayout_indicator = (LinearLayout)findViewById(R.id.id_stickynavlayout_indicator);          img_index_detail_zan = (ImageView)findViewById(R.id.img_index_detail_zan);            //linear_index_detail_seekbar = (LinearLayout) findViewById(R.id.linear_index_detail_seekbar);          //HideTextSizeAnimator(100);        }        @Override      public boolean onCreateOptionsMenu(Menu menu) {          // Inflate the menu; this adds items to the action bar if it is present.          getMenuInflater().inflate(R.menu.menu_index_detail, menu);          return true;      }        @Override      public boolean onOptionsItemSelected(MenuItem item) {          // Handle action bar item clicks here. The action bar will          // automatically handle clicks on the Home/Up button, so long          // as you specify a parent activity in AndroidManifest.xml.          int id = item.getItemId();            //noinspection SimplifiableIfStatement          if (id == R.id.action_settings) {              return true;          }            return super.onOptionsItemSelected(item);      }        @Override      public void onClick(View v) {        }  }

      OK,我们来看一下效果,效果图如下:

     


       

功能还不错,Toolbar出来了,侧滑也能关闭页面了,可是为什么侧滑出来背景是黑的啊。这就不好看了。背景应该是前一个页面啊。这是因为我们虽然进行了侧滑,  可是这个activity的背景是黑的,不是透明的,所以显示不出来前一个页面,我们只要把它的背景设置成透明就OK了,我们后面还要有几个页面使用这个效果,所以我们把  这个设置,放到style.xml文件中,我们来修改我们的style.xml文件.
        
<resources>        <style name="AppBaseTheme" parent="Theme.AppCompat.Light.NoActionBar">            <!-- toolbar(actionbar)颜色 -->          <item name="colorPrimary">@color/titleBlue</item>          <!-- 状态栏颜色 -->          <item name="colorPrimaryDark">#3A5FCD</item>          <!--toolbar文字的颜色-->          <item name="@android:textColorPrimary">@android:color/white</item>          <!-- 窗口的背景颜色 -->          <item name="android:windowBackground">@android:color/white</item>            <!--toolbar上菜单文字的颜色-->          <item name="actionMenuTextColor">#ffffff</item>        </style>        <!--让侧滑页面在侧滑时,背景透明,让AndroidManifest.xml文件的主样式继承它-->      <style name="AppTheme" parent="@style/AppBaseTheme">          <item name="android:windowIsTranslucent">true</item>      </style>  </resources>

      AndroidManifest.xml 文件的application中的android:theme的样式修改为AppTheme。好让我们看一下修改后的效果。

     


       OK,侧滑关掉页面我们完成了,现在我们来从服务器读取数据,给控件赋值,然后看一下我们中间的内容区是否和我们想的一样。

       为了得到页面显示的内容,我们先做一个class,做为models
       goodAnswer.java
      

/**   * 内容页显示字段   * Created by cg on 2015/11/10.   */  public class goodAnswer {      private int questionID;                       //问题id      private String questionTitle;                 //问题的标题      private int userID;                           //答题者的id      private String userName;                      //答题者姓名      private String userProfile;                   //答题者简介      private String answerContent;                 //答题内容      private int aZambia;                          //答题被点选次数      private int ahelpId;                          //对自己是否有帮助      private int userCollectionId;                 //是否收藏      private String userPic;                       //用户照片      private int answerNum;                        //回复数      private int userThank;                        //是否感谢      private int commentNum;        public goodAnswer() {      }        public goodAnswer(int questionID, String questionTitle, int userID, String userName, String userProfile, String answerContent, int aZambia, int ahelpId, int userCollectionId, String userPic, int answerNum, int userThank) {          this.questionID = questionID;          this.questionTitle = questionTitle;          this.userID = userID;          this.userName = userName;          this.userProfile = userProfile;          this.answerContent = answerContent;          this.aZambia = aZambia;          this.ahelpId = ahelpId;          this.userCollectionId = userCollectionId;          this.userPic = userPic;          this.answerNum = answerNum;          this.userThank = userThank;      }        public int getQuestionID() {          return questionID;      }        public void setQuestionID(int questionID) {          this.questionID = questionID;      }        public String getQuestionTitle() {          return questionTitle;      }        public void setQuestionTitle(String questionTitle) {          this.questionTitle = questionTitle;      }        public int getUserID() {          return userID;      }        public void setUserID(int userID) {          this.userID = userID;      }        public String getUserName() {          return userName;      }        public void setUserName(String userName) {          this.userName = userName;      }        public String getUserProfile() {          return userProfile;      }        public void setUserProfile(String userProfile) {          this.userProfile = userProfile;      }        public String getAnswerContent() {          return answerContent;      }        public void setAnswerContent(String answerContent) {          this.answerContent = answerContent;      }        public int getaZambia() {          return aZambia;      }        public void setaZambia(int aZambia) {          this.aZambia = aZambia;      }        public int getAhelpId() {          return ahelpId;      }        public void setAhelpId(int ahelpId) {          this.ahelpId = ahelpId;      }        public int getUserCollectionId() {          return userCollectionId;      }        public void setUserCollectionId(int userCollectionId) {          this.userCollectionId = userCollectionId;      }        public String getUserPic() {          return userPic;      }        public void setUserPic(String userPic) {          this.userPic = userPic;      }        public int getAnswerNum() {          return answerNum;      }        public void setAnswerNum(int answerNum) {          this.answerNum = answerNum;      }        public int getUserThank() {          return userThank;      }        public void setUserThank(int userThank) {          this.userThank = userThank;      }  }

       好,我们来看一下Index_detailActivity.java的代码

      

import android.app.ProgressDialog;  import android.content.SharedPreferences;  import android.graphics.Bitmap;  import android.graphics.BitmapFactory;  import android.graphics.drawable.Drawable;  import android.os.Bundle;  import android.os.Environment;  import android.os.Handler;  import android.os.Message;  import android.support.v7.widget.ShareActionProvider;  import android.support.v7.widget.Toolbar;  import android.text.Html;  import android.util.Log;  import android.view.Menu;  import android.view.MenuItem;  import android.view.View;  import android.widget.ImageView;  import android.widget.LinearLayout;  import android.widget.ScrollView;  import android.widget.SeekBar;  import android.widget.TextView;  import android.widget.Toast;    import com.android.volley.RequestQueue;  import com.android.volley.toolbox.ImageLoader;  import com.android.volley.toolbox.NetworkImageView;  import com.android.volley.toolbox.Volley;  import com.example.cg.zhihu_one.models.goodAnswer;  import com.example.cg.zhihu_one.untils.SwipeBackToolBarActivity;  import com.example.cg.zhihu_one.untils.configStatic;  import com.example.cg.zhihu_one.untils.imagesUntils;  import com.example.cg.zhihu_one.untils.webservicesUntils;  import com.loopj.android.http.AsyncHttpClient;  import com.loopj.android.http.BinaryHttpResponseHandler;    import org.apache.http.Header;  import org.json.JSONException;  import org.json.JSONObject;    import java.io.File;  import java.io.FileOutputStream;  import java.io.IOException;  import java.io.OutputStream;  import java.util.Date;    import me.imid.swipebacklayout.lib.SwipeBackLayout;    public class Index_detailActivity extends SwipeBackToolBarActivity implements View.OnClickListener {        private SwipeBackLayout mSwipeBackLayout;                           //定义侧滑退出此activity        private Toolbar toolbar;                                            //定义toolbar        private int qid;                                                    //定义接到的问题id      private String questionTitle;                                       //定义问题的标题        private ProgressDialog myProgressDialog;                            //定义信息等等控件        private TextView txt_index_detail_title;                            //定义问题的标题      private NetworkImageView netimg_index_detail_userpic;               //定义用户头像      private TextView txt_index_detail_userName;                         //定义用户名字      private TextView txt_index_detail_userRemark;                       //定义用户简介      private ImageView img_index_detail_zan;                             //定义点赞的图标      private TextView txt_index_detail_zanNum;                           //定义点赞数      private ScrollView scorl_main;                                      //内容滚动条      private TextView txt_index_detail_content;                          //定义内容      private LinearLayout linear_index_detail_bottomtitle;               //定义底部工具栏      private LinearLayout id_stickynavlayout_indicator;        private float oldy;                                                 //定义滚动scrollview的前一步滚动的值      private boolean isHideBottom = false;                               //是否隐藏底部工具栏          private TextView txt_index_detail_help;                             //定义底部工具栏,帮助      private boolean isHelp = false;                                     //是否帮助,默认为否      private TextView txt_index_detail_thank;                            //定义底部工具栏,感谢      private boolean isThank = false;                                    //是否感谢,默认为否      private TextView txt_index_detail_Collection;                       //定义底部工具栏,收藏      private boolean isCollection = false;                               //是否收藏,默认为否      private TextView txt_index_detail_Comment;                          //定义底部工具栏,评论      private boolean isComment = false;                                  //是否评价,默认为否        private goodAnswer gAnswer;                                         //定义最佳回答的类      //定义volley      private RequestQueue mQueue;      private ImageLoader imageLoader;        private String answerContent;                                       //定义答案,主要是为了重新加载其中的图片      //private PopupWindow popWin;                                       //定义更多弹出对话框        private ShareActionProvider mShareActionProvider;        private LinearLayout linear_index_detail_zan;                       //点赞按钮      private int isZan = 0;                                              //是否点了赞同或是反对 0:未点 1:赞同  2:反对        private boolean isHideTextSize = true;                              //是否隐藏底部文字大小调整,默认是隐藏 true      private LinearLayout linear_index_detail_seekbar;                   //底部文字大小调整      private SeekBar seekbar_index_detail;                               //底部调整文字大小seebar        @Override      protected void onCreate(Bundle savedInstanceState) {          super.onCreate(savedInstanceState);          setContentView(R.layout.activity_index_detail);            qid = getIntent().getIntExtra("questionID", 0);              //从列表页,接收问题的id          questionTitle = getIntent().getStringExtra("questionTitle"); //接收到的标题            mSwipeBackLayout = getSwipeBackLayout();          int edgeFlag = SwipeBackLayout.EDGE_LEFT;       //从右向左滑动          //int edgeFlag = SwipeBackLayout.EDGE_RIGHT;      //从左向右滑动          //int edgeFlag = SwipeBackLayout.EDGE_BOTTOM;     //从下向上滑动          //int edgeFlag = SwipeBackLayout.EDGE_ALL;          //从右,右,下都可以滑动          mSwipeBackLayout.setEdgeTrackingEnabled(edgeFlag);            toolbar = (Toolbar)this.findViewById(R.id.toolbar);          toolbar.setTitle(questionTitle);                     // 标题的文字需在setSupportActionBar之前,不然会无效          setSupportActionBar(toolbar);            //初始化Volley,为用户照片显示          mQueue = Volley.newRequestQueue(this);          imageLoader = new ImageLoader(mQueue, new imagesUntils.BitmapCache() {              @Override              public Bitmap getBitmap(String s) {                  return null;              }                @Override              public void putBitmap(String s, Bitmap bitmap) {                }          });            initControls();            initData(qid);      }        /**       * 初始化各控件       */      private void initControls() {          txt_index_detail_title = (TextView)findViewById(R.id.txt_index_detail_title);          //注意这里,我们把标题的内容给TextView赋值,是为了能让我们自定义的StickNavLayout布局去算一下,它的高度。          //因为我们的数据值是通过异步从远程服务器中得到了,如果现在不给值,会有一个时间差,会造成计算高度有误          txt_index_detail_title.setText(questionTitle);          netimg_index_detail_userpic = (NetworkImageView)findViewById(R.id.netimg_index_detail_userpic);          txt_index_detail_userName = (TextView)findViewById(R.id.txt_index_detail_userName);          txt_index_detail_userRemark = (TextView)findViewById(R.id.txt_index_detail_userRemark);          txt_index_detail_zanNum = (TextView)findViewById(R.id.txt_index_detail_zanNum);          txt_index_detail_content = (TextView)findViewById(R.id.txt_index_detail_content);          txt_index_detail_content.setOnClickListener(this);          linear_index_detail_bottomtitle = (LinearLayout)findViewById(R.id.linear_index_detail_bottomtitle);          id_stickynavlayout_indicator = (LinearLayout)findViewById(R.id.id_stickynavlayout_indicator);          img_index_detail_zan = (ImageView)findViewById(R.id.img_index_detail_zan);            //linear_index_detail_seekbar = (LinearLayout) findViewById(R.id.linear_index_detail_seekbar);          //HideTextSizeAnimator(100);        }        /**       * 初始化数据,根据问题id,取出相应的问题信息       * @param qid       */      private void initData(final int qid) {            // 初始化数据和数据源          myProgressDialog = new ProgressDialog(this);          myProgressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);  //设置风格为圆形进度条          myProgressDialog.setTitle("提示");                                 //设置标题          myProgressDialog.setMessage("数据加载中,请稍等...");                 //设置内容          myProgressDialog.setIndeterminate(false);                         //设置进度是否为不明确          myProgressDialog.setCancelable(true);                             //设置进度条是否可以按退回键取消          myProgressDialog.show();            new Thread(new Runnable() {              @Override              public void run() {                  Message msg = new Message();                    try{                      String soapObject = webservicesUntils.getIndexDetailgoodAnswer(qid);                        if(soapObject!="0") {                          try {                                gAnswer = new goodAnswer();                                //操作单条json数据                              JSONObject jsonAnswer = new JSONObject(soapObject);                                gAnswer.setQuestionID(jsonAnswer.getInt("questionID"));                              gAnswer.setQuestionTitle(jsonAnswer.getString("questionTitle"));                              gAnswer.setUserID(jsonAnswer.getInt("userID"));                              gAnswer.setUserName(jsonAnswer.getString("userName"));                              gAnswer.setUserProfile(jsonAnswer.getString("userProfile"));                              gAnswer.setAnswerContent(jsonAnswer.getString("answerContent"));                              gAnswer.setaZambia(jsonAnswer.getInt("aZambia"));                              gAnswer.setAhelpId(jsonAnswer.getInt("ahelpId"));                              gAnswer.setUserCollectionId(jsonAnswer.getInt("userCollectionId"));                              gAnswer.setUserPic(jsonAnswer.getString("userPic"));                              gAnswer.setAnswerNum(jsonAnswer.getInt("answerNum"));                              gAnswer.setUserThank(jsonAnswer.getInt("userThank"));                            } catch (JSONException e) {                              // TODO Auto-generated catch block                              e.printStackTrace();                          }                      }                          msg.arg1 = 1;                      msg.obj = gAnswer;                        handler.sendMessage(msg);                    }catch (Exception ex){                      msg.arg1 = 2;                  }              }          }).start();        }        Handler handler = new Handler(){            @Override          public void handleMessage(Message msg) {              if(msg.arg1==1)              {                    toolbar.setTitle(gAnswer.getQuestionTitle());                     // 标题的文字需在setSupportActionBar之前,不然会无效                  setSupportActionBar(toolbar);                  //actionBar.setTitle(gAnswer.getQuestionTitle());                          //为actionbar设置标题                  txt_index_detail_title.setText(gAnswer.getQuestionTitle());              //为标题赋值                  //为图片控件加载图片,采用NetworkImageView控件。                  //第一项是加载图片控件的默认图片,一般是图片加载中,这样的图片                  //第二项是当发生错误的时候加载的图片,如网络图片路径不对或是加载失败的时候显示的图片                  //第三项就是加载网络图片了                  netimg_index_detail_userpic.setDefaultImageResId(R.drawable.img_empty_followers);                  netimg_index_detail_userpic.setErrorImageResId(R.drawable.img_empty_followers);                  netimg_index_detail_userpic.setImageUrl(gAnswer.getUserPic(), imageLoader);                    txt_index_detail_userName.setText(gAnswer.getUserName());                //为用户名赋值                  txt_index_detail_userRemark.setText(gAnswer.getUserProfile());           //用户简介                  txt_index_detail_zanNum.setText(gAnswer.getaZambia() + "");              //点赞数                  answerContent = gAnswer.getAnswerContent();                  //txt_index_detail_Comment.setText("评论  " + gAnswer.getAnswerNum());      //评论数                  //txt_index_detail_content.setText(answerContent);                  //从系统设置中,读取默认的字体大小                  SharedPreferences preferences = getSharedPreferences(configStatic.SHAREDPREFERENCES_NAME, MODE_PRIVATE);                  int contentTextSize = preferences.getInt("contentTextSize", 14);                  txt_index_detail_content.setTextSize(contentTextSize);                  //seekbar_index_detail.setProgress((contentTextSize - 10) / 2);                  txt_index_detail_content.setText(Html.fromHtml(answerContent, imageGetter, null));                    /*if(gAnswer.getAhelpId()!=0)                  {                      txt_index_detail_help.setCompoundDrawablesWithIntrinsicBounds(null, getResources().getDrawable(R.drawable.ic_nohelped), null, null);                      txt_index_detail_help.setText(R.string.index_detail_nohelp);                      isHelp = true;                  }                  if(gAnswer.getUserThank()!=0)                  {                      txt_index_detail_thank.setCompoundDrawablesWithIntrinsicBounds(null, getResources().getDrawable(R.drawable.ic_thanked), null, null);                      txt_index_detail_thank.setText(R.string.index_detail_thanked);                  }                  if(gAnswer.getUserCollectionId()!=0)                  {                      txt_index_detail_Collection.setCompoundDrawablesWithIntrinsicBounds(null, getResources().getDrawable(R.drawable.ic_collected), null, null);                      txt_index_detail_Collection.setText(R.string.index_detail_collectioned);                      isCollection = true;                  }                    HideTextSizeAnimator(100);*/                }else              {                  Toast.makeText(Index_detailActivity.this, "数据加载失败!", Toast.LENGTH_LONG).show();              }                myProgressDialog.dismiss();          }      };        /**       * 处理 TextView中的图片,对图片地址进行处理       */      Html.ImageGetter imageGetter = new Html.ImageGetter(){            @Override          public Drawable getDrawable(String source) {                Drawable drawable=null;              /**               * 判断图片是本地图片还是网络图片,如果是本地图片,直接调用,如果是网络图片,先下载再调用               * */              if(source.indexOf("http://")!=-1) {                  //showPic(source);              }else              {                  drawable=Drawable.createFromPath(source);                  drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());              }              return drawable;          }      };        @Override      public boolean onCreateOptionsMenu(Menu menu) {          // Inflate the menu; this adds items to the action bar if it is present.          getMenuInflater().inflate(R.menu.menu_index_detail, menu);          return true;      }        @Override      public boolean onOptionsItemSelected(MenuItem item) {          // Handle action bar item clicks here. The action bar will          // automatically handle clicks on the Home/Up button, so long          // as you specify a parent activity in AndroidManifest.xml.          int id = item.getItemId();            //noinspection SimplifiableIfStatement          if (id == R.id.action_settings) {              return true;          }            return super.onOptionsItemSelected(item);      }        @Override      public void onClick(View v) {        }        /**       * TextView中加载图片的处理,主要是根据文本中图片的地址,把网络上的图片下到手机中,以方便读取       * @param url       */      private void showPic(final String url) {          AsyncHttpClient client = new AsyncHttpClient();          // 指定文件类型          String[] allowedContentTypes = new String[]{"image/png", "image/jpeg"};          // 获取二进制数据如图片和其他文件          client.get(url, new BinaryHttpResponseHandler(allowedContentTypes) {                @Override              public void onSuccess(int statusCode, Header[] headers,                                    byte[] binaryData) {                  String tempPath = Environment.getExternalStorageDirectory()                          .getPath() + "/" + new Date().getTime() + ".jpg";                  // TODO Auto-generated method stub                  // 下载成功后需要做的工作                  //progress.setProgress(0);                  //                  Log.e("binaryData:", "共下载了:" + binaryData.length);                  //                  Bitmap bmp = BitmapFactory.decodeByteArray(binaryData, 0,                          binaryData.length);                    File file = new File(tempPath);                  // 压缩格式                  Bitmap.CompressFormat format = Bitmap.CompressFormat.JPEG;                  // 压缩比例                  int quality = 100;                  try {                      // 若存在则删除                      if (file.exists())                          file.delete();                      // 创建文件                      file.createNewFile();                      //                      OutputStream stream = new FileOutputStream(file);                      // 压缩输出                      bmp.compress(format, quality, stream);                      // 关闭                      stream.close();                      //                      //Toast.makeText(MainActivity.this, "下载成功\n" + tempPath,                      //Toast.LENGTH_LONG).show();                        Log.e("url", url);                      Log.e("tempPath", tempPath);                        //此处是当图片已经下到本地之后,再根据本地地址重新加载一次文字内容,这样图片就加载到了TextView中                      //这里一直没有想到更好的方法                      answerContent = answerContent.replace(url, tempPath);                        txt_index_detail_content.setText(Html.fromHtml(answerContent, imageGetter, null));                    } catch (IOException e) {                      // TODO Auto-generated catch block                      e.printStackTrace();                  }                }                @Override              public void onFailure(int statusCode, Header[] headers,                                    byte[] binaryData, Throwable error) {                  // TODO Auto-generated method stub                  Toast.makeText(Index_detailActivity.this, "下载失败", Toast.LENGTH_LONG).show();              }                  public void onProgress(int bytesWritten, int totalSize) {                  // TODO Auto-generated method stub                  super.onProgress(bytesWritten, totalSize);                  int count = (int) ((bytesWritten * 1.0 / totalSize) * 100);                  // 下载进度显示                  //progress.setProgress(count);                  Log.e("下载 Progress>>>>>", bytesWritten + " / " + totalSize);                }                @Override              public void onRetry(int retryNo) {                  // TODO Auto-generated method stub                  super.onRetry(retryNo);                  // 返回重试次数              }            });      }  }

      知识点:

          1,因为知乎这个程序是分app和web两个版本的,很多问题都是在web端输入的,所以它app内容部分,正常是用webview调html的代码实现的,在这里我只是为了简化,就直接使用了TextView。这里我们使用Html.fromHtml方法来加载内容,可以解析一部分html代码,但不是全部的,比较表格 table它就不认。所以这里的内容我就做了点简单的样式,就是回车。我们要知道和学习的就是Html.fromHtml

           2,正文中的图片下载,我们使用的是第三方插件,android-async-http。它的官网是https://github.com/loopj/android-async-http。我们在android studio中只要引入compile 'com.loopj.android:android-async-http:1.4.8'即可。
     好,我们看一下代码

    

import android.app.ProgressDialog;  import android.content.SharedPreferences;  import android.graphics.Bitmap;  import android.graphics.BitmapFactory;  import android.graphics.drawable.Drawable;  import android.os.Bundle;  import android.os.Environment;  import android.os.Handler;  import android.os.Message;  import android.support.v7.widget.ShareActionProvider;  import android.support.v7.widget.Toolbar;  import android.text.Html;  import android.util.Log;  import android.view.Menu;  import android.view.MenuItem;  import android.view.View;  import android.widget.ImageView;  import android.widget.LinearLayout;  import android.widget.ScrollView;  import android.widget.SeekBar;  import android.widget.TextView;  import android.widget.Toast;    import com.android.volley.RequestQueue;  import com.android.volley.toolbox.ImageLoader;  import com.android.volley.toolbox.NetworkImageView;  import com.android.volley.toolbox.Volley;  import com.example.cg.zhihu_one.models.goodAnswer;  import com.example.cg.zhihu_one.untils.SwipeBackToolBarActivity;  import com.example.cg.zhihu_one.untils.configStatic;  import com.example.cg.zhihu_one.untils.imagesUntils;  import com.example.cg.zhihu_one.untils.webservicesUntils;  import com.loopj.android.http.AsyncHttpClient;  import com.loopj.android.http.BinaryHttpResponseHandler;    import org.apache.http.Header;  import org.json.JSONException;  import org.json.JSONObject;    import java.io.File;  import java.io.FileOutputStream;  import java.io.IOException;  import java.io.OutputStream;  import java.util.Date;    import me.imid.swipebacklayout.lib.SwipeBackLayout;    public class Index_detailActivity extends SwipeBackToolBarActivity implements View.OnClickListener {        private SwipeBackLayout mSwipeBackLayout;                           //定义侧滑退出此activity        private Toolbar toolbar;                                            //定义toolbar        private int qid;                                                    //定义接到的问题id      private String questionTitle;                                       //定义问题的标题        private ProgressDialog myProgressDialog;                            //定义信息等等控件        private TextView txt_index_detail_title;                            //定义问题的标题      private NetworkImageView netimg_index_detail_userpic;               //定义用户头像      private TextView txt_index_detail_userName;                         //定义用户名字      private TextView txt_index_detail_userRemark;                       //定义用户简介      private ImageView img_index_detail_zan;                             //定义点赞的图标      private TextView txt_index_detail_zanNum;                           //定义点赞数      private ScrollView scorl_main;                                      //内容滚动条      private TextView txt_index_detail_content;                          //定义内容      private LinearLayout linear_index_detail_bottomtitle;               //定义底部工具栏      private LinearLayout id_stickynavlayout_indicator;        private float oldy;                                                 //定义滚动scrollview的前一步滚动的值      private boolean isHideBottom = false;                               //是否隐藏底部工具栏          private TextView txt_index_detail_help;                             //定义底部工具栏,帮助      private boolean isHelp = false;                                     //是否帮助,默认为否      private TextView txt_index_detail_thank;                            //定义底部工具栏,感谢      private boolean isThank = false;                                    //是否感谢,默认为否      private TextView txt_index_detail_Collection;                       //定义底部工具栏,收藏      private boolean isCollection = false;                               //是否收藏,默认为否      private TextView txt_index_detail_Comment;                          //定义底部工具栏,评论      private boolean isComment = false;                                  //是否评价,默认为否        private goodAnswer gAnswer;                                         //定义最佳回答的类      //定义volley      private RequestQueue mQueue;      private ImageLoader imageLoader;        private String answerContent;                                       //定义答案,主要是为了重新加载其中的图片      //private PopupWindow popWin;                                       //定义更多弹出对话框        private ShareActionProvider mShareActionProvider;        private LinearLayout linear_index_detail_zan;                       //点赞按钮      private int isZan = 0;                                              //是否点了赞同或是反对 0:未点 1:赞同  2:反对        private boolean isHideTextSize = true;                              //是否隐藏底部文字大小调整,默认是隐藏 true      private LinearLayout linear_index_detail_seekbar;                   //底部文字大小调整      private SeekBar seekbar_index_detail;                               //底部调整文字大小seebar        @Override      protected void onCreate(Bundle savedInstanceState) {          super.onCreate(savedInstanceState);          setContentView(R.layout.activity_index_detail);            qid = getIntent().getIntExtra("questionID", 0);              //从列表页,接收问题的id          questionTitle = getIntent().getStringExtra("questionTitle"); //接收到的标题            mSwipeBackLayout = getSwipeBackLayout();          int edgeFlag = SwipeBackLayout.EDGE_LEFT;       //从右向左滑动          //int edgeFlag = SwipeBackLayout.EDGE_RIGHT;      //从左向右滑动          //int edgeFlag = SwipeBackLayout.EDGE_BOTTOM;     //从下向上滑动          //int edgeFlag = SwipeBackLayout.EDGE_ALL;          //从右,右,下都可以滑动          mSwipeBackLayout.setEdgeTrackingEnabled(edgeFlag);            toolbar = (Toolbar)this.findViewById(R.id.toolbar);          toolbar.setTitle(questionTitle);                     // 标题的文字需在setSupportActionBar之前,不然会无效          setSupportActionBar(toolbar);            //初始化Volley,为用户照片显示          mQueue = Volley.newRequestQueue(this);          imageLoader = new ImageLoader(mQueue, new imagesUntils.BitmapCache() {              @Override              public Bitmap getBitmap(String s) {                  return null;              }                @Override              public void putBitmap(String s, Bitmap bitmap) {                }          });            initControls();            initData(qid);      }        /**       * 初始化各控件       */      private void initControls() {          txt_index_detail_title = (TextView)findViewById(R.id.txt_index_detail_title);          //注意这里,我们把标题的内容给TextView赋值,是为了能让我们自定义的StickNavLayout布局去算一下,它的高度。          //因为我们的数据值是通过异步从远程服务器中得到了,如果现在不给值,会有一个时间差,会造成计算高度有误          txt_index_detail_title.setText(questionTitle);          netimg_index_detail_userpic = (NetworkImageView)findViewById(R.id.netimg_index_detail_userpic);          txt_index_detail_userName = (TextView)findViewById(R.id.txt_index_detail_userName);          txt_index_detail_userRemark = (TextView)findViewById(R.id.txt_index_detail_userRemark);          txt_index_detail_zanNum = (TextView)findViewById(R.id.txt_index_detail_zanNum);          txt_index_detail_content = (TextView)findViewById(R.id.txt_index_detail_content);          txt_index_detail_content.setOnClickListener(this);          linear_index_detail_bottomtitle = (LinearLayout)findViewById(R.id.linear_index_detail_bottomtitle);          id_stickynavlayout_indicator = (LinearLayout)findViewById(R.id.id_stickynavlayout_indicator);          img_index_detail_zan = (ImageView)findViewById(R.id.img_index_detail_zan);            //linear_index_detail_seekbar = (LinearLayout) findViewById(R.id.linear_index_detail_seekbar);          //HideTextSizeAnimator(100);        }        /**       * 初始化数据,根据问题id,取出相应的问题信息       * @param qid       */      private void initData(final int qid) {            // 初始化数据和数据源          myProgressDialog = new ProgressDialog(this);          myProgressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);  //设置风格为圆形进度条          myProgressDialog.setTitle("提示");                                 //设置标题          myProgressDialog.setMessage("数据加载中,请稍等...");                 //设置内容          myProgressDialog.setIndeterminate(false);                         //设置进度是否为不明确          myProgressDialog.setCancelable(true);                             //设置进度条是否可以按退回键取消          myProgressDialog.show();            new Thread(new Runnable() {              @Override              public void run() {                  Message msg = new Message();                    try{                      String soapObject = webservicesUntils.getIndexDetailgoodAnswer(qid);                        if(soapObject!="0") {                          try {                                gAnswer = new goodAnswer();                                //操作单条json数据                              JSONObject jsonAnswer = new JSONObject(soapObject);                                gAnswer.setQuestionID(jsonAnswer.getInt("questionID"));                              gAnswer.setQuestionTitle(jsonAnswer.getString("questionTitle"));                              gAnswer.setUserID(jsonAnswer.getInt("userID"));                              gAnswer.setUserName(jsonAnswer.getString("userName"));                              gAnswer.setUserProfile(jsonAnswer.getString("userProfile"));                              gAnswer.setAnswerContent(jsonAnswer.getString("answerContent"));                              gAnswer.setaZambia(jsonAnswer.getInt("aZambia"));                              gAnswer.setAhelpId(jsonAnswer.getInt("ahelpId"));                              gAnswer.setUserCollectionId(jsonAnswer.getInt("userCollectionId"));                              gAnswer.setUserPic(jsonAnswer.getString("userPic"));                              gAnswer.setAnswerNum(jsonAnswer.getInt("answerNum"));                              gAnswer.setUserThank(jsonAnswer.getInt("userThank"));                            } catch (JSONException e) {                              // TODO Auto-generated catch block                              e.printStackTrace();                          }                      }                          msg.arg1 = 1;                      msg.obj = gAnswer;                        handler.sendMessage(msg);                    }catch (Exception ex){                      msg.arg1 = 2;                  }              }          }).start();        }        Handler handler = new Handler(){            @Override          public void handleMessage(Message msg) {              if(msg.arg1==1)              {                    toolbar.setTitle(gAnswer.getQuestionTitle());                     // 标题的文字需在setSupportActionBar之前,不然会无效                  setSupportActionBar(toolbar);                  //actionBar.setTitle(gAnswer.getQuestionTitle());                          //为actionbar设置标题                  txt_index_detail_title.setText(gAnswer.getQuestionTitle());              //为标题赋值                  //为图片控件加载图片,采用NetworkImageView控件。                  //第一项是加载图片控件的默认图片,一般是图片加载中,这样的图片                  //第二项是当发生错误的时候加载的图片,如网络图片路径不对或是加载失败的时候显示的图片                  //第三项就是加载网络图片了                  netimg_index_detail_userpic.setDefaultImageResId(R.drawable.img_empty_followers);                  netimg_index_detail_userpic.setErrorImageResId(R.drawable.img_empty_followers);                  netimg_index_detail_userpic.setImageUrl(gAnswer.getUserPic(), imageLoader);                    txt_index_detail_userName.setText(gAnswer.getUserName());                //为用户名赋值                  txt_index_detail_userRemark.setText(gAnswer.getUserProfile());           //用户简介                  txt_index_detail_zanNum.setText(gAnswer.getaZambia() + "");              //点赞数                  answerContent = gAnswer.getAnswerContent();                  //txt_index_detail_Comment.setText("评论  " + gAnswer.getAnswerNum());      //评论数                  //txt_index_detail_content.setText(answerContent);                  //从系统设置中,读取默认的字体大小                  SharedPreferences preferences = getSharedPreferences(configStatic.SHAREDPREFERENCES_NAME, MODE_PRIVATE);                  int contentTextSize = preferences.getInt("contentTextSize", 14);                  txt_index_detail_content.setTextSize(contentTextSize);                  //seekbar_index_detail.setProgress((contentTextSize - 10) / 2);                  txt_index_detail_content.setText(Html.fromHtml(answerContent, imageGetter, null));                    /*if(gAnswer.getAhelpId()!=0)                  {                      txt_index_detail_help.setCompoundDrawablesWithIntrinsicBounds(null, getResources().getDrawable(R.drawable.ic_nohelped), null, null);                      txt_index_detail_help.setText(R.string.index_detail_nohelp);                      isHelp = true;                  }                  if(gAnswer.getUserThank()!=0)                  {                      txt_index_detail_thank.setCompoundDrawablesWithIntrinsicBounds(null, getResources().getDrawable(R.drawable.ic_thanked), null, null);                      txt_index_detail_thank.setText(R.string.index_detail_thanked);                  }                  if(gAnswer.getUserCollectionId()!=0)                  {                      txt_index_detail_Collection.setCompoundDrawablesWithIntrinsicBounds(null, getResources().getDrawable(R.drawable.ic_collected), null, null);                      txt_index_detail_Collection.setText(R.string.index_detail_collectioned);                      isCollection = true;                  }                    HideTextSizeAnimator(100);*/                }else              {                  Toast.makeText(Index_detailActivity.this, "数据加载失败!", Toast.LENGTH_LONG).show();              }                myProgressDialog.dismiss();          }      };        /**       * 处理 TextView中的图片,对图片地址进行处理       */      Html.ImageGetter imageGetter = new Html.ImageGetter(){            @Override          public Drawable getDrawable(String source) {                Drawable drawable=null;              /**               * 判断图片是本地图片还是网络图片,如果是本地图片,直接调用,如果是网络图片,先下载再调用               * */              if(source.indexOf("http://")!=-1) {                  showPic(source);              }else              {                  drawable=Drawable.createFromPath(source);                  drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());              }              return drawable;          }      };        @Override      public boolean onCreateOptionsMenu(Menu menu) {          // Inflate the menu; this adds items to the action bar if it is present.          getMenuInflater().inflate(R.menu.menu_index_detail, menu);          return true;      }        @Override      public boolean onOptionsItemSelected(MenuItem item) {          // Handle action bar item clicks here. The action bar will          // automatically handle clicks on the Home/Up button, so long          // as you specify a parent activity in AndroidManifest.xml.          int id = item.getItemId();            //noinspection SimplifiableIfStatement          if (id == R.id.action_settings) {              return true;          }            return super.onOptionsItemSelected(item);      }        @Override      public void onClick(View v) {        }        /**       * TextView中加载图片的处理,主要是根据文本中图片的地址,把网络上的图片下到手机中,以方便读取       * @param url       */      private void showPic(final String url) {          AsyncHttpClient client = new AsyncHttpClient();          // 指定文件类型          String[] allowedContentTypes = new String[]{"image/png", "image/jpeg"};          // 获取二进制数据如图片和其他文件          client.get(url, new BinaryHttpResponseHandler(allowedContentTypes) {                @Override              public void onSuccess(int statusCode, Header[] headers,                                    byte[] binaryData) {                  String tempPath = Environment.getExternalStorageDirectory()                          .getPath() + "/" + new Date().getTime() + ".jpg";                  // TODO Auto-generated method stub                  // 下载成功后需要做的工作                  //progress.setProgress(0);                  //                  Log.e("binaryData:", "共下载了:" + binaryData.length);                  //                  Bitmap bmp = BitmapFactory.decodeByteArray(binaryData, 0,                          binaryData.length);                    File file = new File(tempPath);                  // 压缩格式                  Bitmap.CompressFormat format = Bitmap.CompressFormat.JPEG;                  // 压缩比例                  int quality = 100;                  try {                      // 若存在则删除                      if (file.exists())                          file.delete();                      // 创建文件                      file.createNewFile();                      //                      OutputStream stream = new FileOutputStream(file);                      // 压缩输出                      bmp.compress(format, quality, stream);                      // 关闭                      stream.close();                      //                      //Toast.makeText(MainActivity.this, "下载成功\n" + tempPath,                      //Toast.LENGTH_LONG).show();                        Log.e("url", url);                      Log.e("tempPath", tempPath);                        //此处是当图片已经下到本地之后,再根据本地地址重新加载一次文字内容,这样图片就加载到了TextView中                      //这里一直没有想到更好的方法                      answerContent = answerContent.replace(url, tempPath);                        txt_index_detail_content.setText(Html.fromHtml(answerContent, imageGetter, null));                    } catch (IOException e) {                      // TODO Auto-generated catch block                      e.printStackTrace();                  }                }                @Override              public void onFailure(int statusCode, Header[] headers,                                    byte[] binaryData, Throwable error) {                  // TODO Auto-generated method stub                  Toast.makeText(Index_detailActivity.this, "下载失败", Toast.LENGTH_LONG).show();              }                  public void onProgress(int bytesWritten, int totalSize) {                  // TODO Auto-generated method stub                  super.onProgress(bytesWritten, totalSize);                  int count = (int) ((bytesWritten * 1.0 / totalSize) * 100);                  // 下载进度显示                  //progress.setProgress(count);                  Log.e("下载 Progress>>>>>", bytesWritten + " / " + totalSize);                }                @Override              public void onRetry(int retryNo) {                  // TODO Auto-generated method stub                  super.onRetry(retryNo);                  // 返回重试次数              }            });      }  }

      程序中我已经加了比较清楚的注解,下面来看一下效果图,是不是图片已经出来了, 呵呵。。。忽略细节

    

      好今天就到这里