//MainActivity
package animtest.com.example.e531.yuekao_test_demo; import android.support.v4.app.Fragment; import android.support.v4.widget.DrawerLayout; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.ImageView; import android.widget.RadioGroup; import android.widget.RelativeLayout; import animtest.com.example.e531.yuekao_test_demo.fragments.IndexFragment; import animtest.com.example.e531.yuekao_test_demo.fragments.MeFragment; import animtest.com.example.e531.yuekao_test_demo.fragments.TopFragment; import animtest.com.example.e531.yuekao_test_demo.fragments.VideoFragment; public class MainActivity extends AppCompatActivity { private ImageView imgTitle; private RelativeLayout relMenu; private DrawerLayout drawerLayout; private RadioGroup radioGroup; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); drawerLayout = (DrawerLayout) findViewById(R.id.mydrawer); imgTitle = (ImageView) findViewById(R.id.img_title); radioGroup = (RadioGroup) findViewById(R.id.rel_navigate); //侧滑菜单的视图 relMenu = (RelativeLayout) findViewById(R.id.rel_menu); imgTitle.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //关闭,侧滑菜单 drawerLayout.closeDrawer(relMenu); } }); radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() { @Override public void onCheckedChanged(RadioGroup group, int checkedId) { if(checkedId==R.id.rb_index){ Log.d("zzz","add index fragment ***********"); addFragment(new IndexFragment()); }else if(checkedId==R.id.rb_top){ addFragment(new TopFragment()); }else if(checkedId==R.id.rb_me){ addFragment(new MeFragment()); }else if(checkedId==R.id.rb_video){ addFragment(new VideoFragment()); } } }); //默认添加"首页" addFragment(new IndexFragment()); } /** * 添加fragment到主页面中 * @param fragment */ public void addFragment(Fragment fragment){ getSupportFragmentManager().beginTransaction().replace(R.id.main_content,fragment).commit(); } }//imageloder类
package animtest.com.example.e531.yuekao_test_demo; import android.app.Application; import com.nostra13.universalimageloader.cache.disc.impl.UnlimitedDiscCache; import com.nostra13.universalimageloader.cache.disc.naming.Md5FileNameGenerator; import com.nostra13.universalimageloader.core.ImageLoader; import com.nostra13.universalimageloader.core.ImageLoaderConfiguration; import java.io.File; /** * Created by e531 on 2017/10/14. */ public class MyApplication extends Application { @Override public void onCreate() { super.onCreate(); File cacheFile=getExternalCacheDir(); ImageLoaderConfiguration config=new ImageLoaderConfiguration.Builder(this) .memoryCacheExtraOptions(480, 800)//缓存图片最大的长和宽 .threadPoolSize(2)//线程池的数量 .threadPriority(4) .memoryCacheSize(2*1024*1024)//设置内存缓存区大小 .diskCacheSize(20*1024*1024)//设置sd卡缓存区大小 .diskCache(new UnlimitedDiscCache(cacheFile))//自定义缓存目录 .writeDebugLogs()//打印日志内容 .diskCacheFileNameGenerator(new Md5FileNameGenerator())//给缓存的文件名进行md5加密处理 .build(); ImageLoader.getInstance().init(config); } }//适配器类
package animtest.com.example.e531.yuekao_test_demo.adapter; import android.content.Context; import android.graphics.Bitmap; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.TextView; import com.nostra13.universalimageloader.core.DisplayImageOptions; import com.nostra13.universalimageloader.core.ImageLoader; import java.util.List; import animtest.com.example.e531.yuekao_test_demo.Bean.Result; import animtest.com.example.e531.yuekao_test_demo.R; /** * Created by e531 on 2017/10/14. */ public class MyAdapter extends BaseAdapter { private List<Result.DataEntity> datas; private Context context; private DisplayImageOptions options; public MyAdapter(List<Result.DataEntity> datas, Context context) { this.datas = datas; this.context = context; options=new DisplayImageOptions.Builder() .cacheInMemory(true)//使用内存缓存 .cacheOnDisk(true)//使用磁盘缓存 .bitmapConfig(Bitmap.Config.RGB_565)//设置图片格式 .build(); } @Override public int getCount() { return datas.size(); } @Override public Object getItem(int position) { return datas.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder = null; if(convertView==null){ convertView=View.inflate(context, R.layout.item,null); holder=new ViewHolder(); holder.tvTitle= (TextView) convertView.findViewById(R.id.tv_title); holder.img= (ImageView) convertView.findViewById(R.id.img); convertView.setTag(holder); }else{ holder=(ViewHolder) convertView.getTag(); } holder.tvTitle.setText(datas.get(position).getTitle()); if(datas.get(position).getImg()==null || datas.get(position).getImg().equals("")){ holder.img.setImageResource(R.mipmap.ic_launcher); }else{ //imageLoader加载图片 ImageLoader.getInstance().displayImage(datas.get(position).getImg(),holder.img,options); } return convertView; } class ViewHolder{ TextView tvTitle; ImageView img; } }//Bean类
package animtest.com.example.e531.yuekao_test_demo.Bean; import java.util.List; /** * Created by e531 on 2017/10/14. */ public class Result { private List<DataEntity> data; private HeaderEntity header; public void setData(List<DataEntity> data) { this.data = data; } public void setHeader(HeaderEntity header) { this.header = header; } public List<DataEntity> getData() { return data; } public HeaderEntity getHeader() { return header; } public class DataEntity { private String summary; private String id; private String title; private String otime; private String source; private String views; private String img; private String advTypeShare; private String url; private String resType; private int countid; public void setSummary(String summary) { this.summary = summary; } public void setId(String id) { this.id = id; } public void setTitle(String title) { this.title = title; } public void setOtime(String otime) { this.otime = otime; } public void setSource(String source) { this.source = source; } public void setViews(String views) { this.views = views; } public void setImg(String img) { this.img = img; } public void setAdvTypeShare(String advTypeShare) { this.advTypeShare = advTypeShare; } public void setUrl(String url) { this.url = url; } public void setResType(String resType) { this.resType = resType; } public void setCountid(int countid) { this.countid = countid; } public String getSummary() { return summary; } public String getId() { return id; } public String getTitle() { return title; } public String getOtime() { return otime; } public String getSource() { return source; } public String getViews() { return views; } public String getImg() { return img; } public String getAdvTypeShare() { return advTypeShare; } public String getUrl() { return url; } public String getResType() { return resType; } public int getCountid() { return countid; } } public class HeaderEntity { /** * pagesize : 20 * last : page_10.json * pre : page_1.json * next : page_2.json * totalsize : 200 * totalpage : 10 * first : page_1.json */ private int pagesize; private String last; private String pre; private String next; private int totalsize; private int totalpage; private String first; public void setPagesize(int pagesize) { this.pagesize = pagesize; } public void setLast(String last) { this.last = last; } public void setPre(String pre) { this.pre = pre; } public void setNext(String next) { this.next = next; } public void setTotalsize(int totalsize) { this.totalsize = totalsize; } public void setTotalpage(int totalpage) { this.totalpage = totalpage; } public void setFirst(String first) { this.first = first; } public int getPagesize() { return pagesize; } public String getLast() { return last; } public String getPre() { return pre; } public String getNext() { return next; } public int getTotalsize() { return totalsize; } public int getTotalpage() { return totalpage; } public String getFirst() { return first; } } }//Bean中的
package animtest.com.example.e531.yuekao_test_demo.Bean; /** * Created by e531 on 2017/10/14. */ public class TabModel { private String title; private String type; public TabModel(String title, String type) { this.title = title; this.type = type; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getType() { return type; } public void setType(String type) { this.type = type; } }//Fragment类(imageloder) 必用
1.ContentFragment
package animtest.com.example.e531.yuekao_test_demo.fragments; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.support.annotation.Nullable; import android.support.v4.app.Fragment; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; import java.lang.reflect.Type; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.List; import animtest.com.example.e531.yuekao_test_demo.Bean.Result; import animtest.com.example.e531.yuekao_test_demo.R; import animtest.com.example.e531.yuekao_test_demo.Utils.MyTask; import animtest.com.example.e531.yuekao_test_demo.adapter.MyAdapter; import animtest.com.example.e531.yuekao_test_demo.view.XListView; /** * Created by e531 on 2017/10/14. */ public class ContentFragment extends Fragment implements XListView.IXListViewListener{ //扩展的listivew private XListView xListView; //分类标识 private String dataType; //第几页 private int pageIndex; //请求的数据url private String requestUrl=""; private MyAdapter adapter; private List<Result.DataEntity> datas=new ArrayList<>(); private int refeshType=1; private Handler myHandler=new Handler(){ @Override public void handleMessage(Message msg) { if(msg.what==1){ xListView.stopRefresh();//关闭 //设置时间 SimpleDateFormat simpleDateFormat=new SimpleDateFormat("HH:ss"); String time=simpleDateFormat.format(new Date(System.currentTimeMillis())); xListView.setRefreshTime(time); }else{ xListView.stopLoadMore(); } } }; @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View view=View.inflate(getActivity(), R.layout.content_layout,null); xListView = (XListView) view.findViewById(R.id.xlv); //设置支持下拉刷新上拉加载 xListView.setPullLoadEnable(true); xListView.setPullLoadEnable(true); //设置接口 xListView.setXListViewListener(this); //得到传过来的参数 Bundle bundle=getArguments(); if(bundle!=null){ dataType=bundle.getString("dataType"); pageIndex=Integer.parseInt(bundle.getString("pageIndex")); //拼接请求的地址 requestUrl="http://mnews.gw.com.cn/wap/data/news/"+dataType+"/page_"+pageIndex+".json"; Log.d("zzz","&&&&"+requestUrl); } requestNetData(); return view; } /** * 进行网络数据的请求 */ private void requestNetData(){ if(!requestUrl.equals("")){ MyTask myTask=new MyTask(new MyTask.Icallbacks() { @Override public void updateUiByjson(String jsonstr) { Log.d("zzz","&&&&"+jsonstr); //进行解析 List<Result> results=new ArrayList<>(); Type type=new TypeToken<List<Result>>(){}.getType(); Gson gson=new Gson(); results=gson.fromJson(jsonstr,type); //得到要显示的数据 if(refeshType==1){ datas.addAll(results.get(0).getData()); }else if(refeshType==2){ datas.addAll(0,results.get(0).getData()); } //设置适配器 setAdapter(); } }); myTask.execute(requestUrl); } } /** * 设置适配器 */ public void setAdapter(){ if(adapter==null){ adapter=new MyAdapter(datas,getActivity()); xListView.setAdapter(adapter); }else{ adapter.notifyDataSetChanged(); } } //刷新 @Override public void onRefresh() { refeshType=2; pageIndex++; requestUrl="http://mnews.gw.com.cn/wap/data/news/"+dataType+"/page_"+pageIndex+".json"; requestNetData(); myHandler.sendEmptyMessageDelayed(1,1000); } //加载更多 @Override public void onLoadMore() { refeshType=1; pageIndex++; requestUrl="http://mnews.gw.com.cn/wap/data/news/"+dataType+"/page_"+pageIndex+".json"; requestNetData(); myHandler.sendEmptyMessageDelayed(2,1000); } }2. IndexFragment
package animtest.com.example.e531.yuekao_test_demo.fragments; import android.os.Bundle; import android.support.annotation.Nullable; import android.support.design.widget.TabLayout; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentPagerAdapter; import android.support.v4.view.ViewPager; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import java.util.ArrayList; import java.util.List; import animtest.com.example.e531.yuekao_test_demo.Bean.TabModel; import animtest.com.example.e531.yuekao_test_demo.R; /** * Created by e531 on 2017/10/14 * */ public class IndexFragment extends Fragment { private ViewPager viewPager; private TabLayout tabLayout; private List<TabModel> lists=new ArrayList<TabModel>(); @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View v=inflater.inflate(R.layout.index_layout,null); viewPager = (ViewPager) v.findViewById(R.id.vp); tabLayout = (TabLayout) v.findViewById(R.id.mytab); //tab标题信息 intTabData(); //设置适配器 ,,得到子fragment的管理者,使用getChildFragmentManager viewPager.setAdapter(new MyAdapter(getChildFragmentManager())); //建立关联 tabLayout.setupWithViewPager(viewPager); //指定加载的页数 http://blog.csdn.net/qq_29134495/article/details/51548002 viewPager.setOffscreenPageLimit(lists.size()); return v; } /** * 初使化tab导航 */ private void intTabData() { lists.add(new TabModel("数据新闻","xbsjxw")); lists.add(new TabModel("快讯","txs")); lists.add(new TabModel("头条","toutiao")); lists.add(new TabModel("精编公告","news/mobile/jbgg")); lists.add(new TabModel("美股","news/mobile/mgxw")); lists.add(new TabModel("港股","news/mobile/ggxw")); lists.add(new TabModel("基金","news/mobile/jjxw")); lists.add(new TabModel("理财","news/mobile/lcxw")); } class MyAdapter extends FragmentPagerAdapter{ public MyAdapter(FragmentManager fm) { super(fm); } //获取tab导航文本 @Override public CharSequence getPageTitle(int position) { return lists.get(position).getTitle(); } @Override public Fragment getItem(int position) { Log.d("zzz","pager adapter ***********"+position); Bundle bundle=new Bundle(); bundle.putString("dataType",lists.get(position).getType()); bundle.putString("pageIndex","1"); ContentFragment contentFragment=new ContentFragment(); contentFragment.setArguments(bundle); return contentFragment; } @Override public int getCount() { return lists.size(); } } }3.MeFragment
package animtest.com.example.e531.yuekao_test_demo.fragments; import android.os.Bundle; import android.support.annotation.Nullable; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import animtest.com.example.e531.yuekao_test_demo.R; /** * Created by e531 on 2017/10/14. */ public class MeFragment extends Fragment { @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View v=inflater.inflate(R.layout.me_layout,null); return v; } }4.TopFragment
package animtest.com.example.e531.yuekao_test_demo.fragments; import android.os.Bundle; import android.support.annotation.Nullable; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import animtest.com.example.e531.yuekao_test_demo.R; /** * Created by e531 on 2017/10/14. */ public class TopFragment extends Fragment { @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View v=inflater.inflate(R.layout.top_layout,null); return v; } }4.VideoFragment
package animtest.com.example.e531.yuekao_test_demo.fragments; import android.os.Bundle; import android.support.annotation.Nullable; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import animtest.com.example.e531.yuekao_test_demo.R; /** * Created by e531 on 2017/10/14. */ public class VideoFragment extends Fragment { @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View v=inflater.inflate(R.layout.video_layout,null); return v; } }//异步请求加解析
package animtest.com.example.e531.yuekao_test_demo.Utils; import android.os.AsyncTask; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; /** * 使用AsyncTask+HttpURLConnection请求数据 * Created by e531 on 2017/10/12. */ public class MyTask extends AsyncTask<String,Void,String> { //申请一个接口类对象 private Icallbacks icallbacks; //将无参构造设置成私有的,使之在外部不能够调用 private MyTask(){} //定义有参构造方法 public MyTask(Icallbacks icallbacks) { this.icallbacks = icallbacks; } @Override protected String doInBackground(String... params) { String str=""; try { //使用HttpUrlConnection URL url=new URL(params[0]); HttpURLConnection connection=(HttpURLConnection) url.openConnection(); connection.setRequestMethod("GET"); connection.setReadTimeout(5000); connection.setConnectTimeout(5000); if(connection.getResponseCode()==200){ InputStream inputStream=connection.getInputStream(); //调用工具类中的静态方法 str=StreamToString.streamToStr(inputStream,"utf-8"); } } catch (MalformedURLException e) { e.printStackTrace(); }catch (IOException e){ e.printStackTrace(); } return str; } @Override protected void onPostExecute(String s) { super.onPostExecute(s); //解析,封装到bean,更新ui组件 icallbacks.updateUiByjson(s); } //定义一个接口 public interface Icallbacks{ /** * 根据回传的json字符串,解析并更新页面组件 * @param jsonstr */ void updateUiByjson(String jsonstr); } }//解析类
package animtest.com.example.e531.yuekao_test_demo.Utils; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; /** * Created by e531 on 2017/10/12. */ public class StreamToString { public static String streamToStr(InputStream inputStream,String chartSet){ StringBuilder builder=new StringBuilder(); try { BufferedReader br=new BufferedReader(new InputStreamReader(inputStream,chartSet)); String con; while ((con=br.readLine())!=null){ builder.append(con); } br.close(); return builder.toString(); } catch (Exception e) { e.printStackTrace(); } return ""; } }//xlistview必用文件
1.XListView
/** * @file XListView.java * @package me.maxwin.view * @create Mar 18, 2012 6:28:41 PM * @author Maxwin * @description An ListView support (a) Pull down to refresh, (b) Pull up to load more. * Implement IXListViewListener, and see stopRefresh() / stopLoadMore(). */ package animtest.com.example.e531.yuekao_test_demo.view; import android.content.Context; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; import android.view.ViewTreeObserver.OnGlobalLayoutListener; import android.view.animation.DecelerateInterpolator; import android.widget.AbsListView; import android.widget.AbsListView.OnScrollListener; import android.widget.ListAdapter; import android.widget.ListView; import android.widget.RelativeLayout; import android.widget.Scroller; import android.widget.TextView; import animtest.com.example.e531.yuekao_test_demo.R; public class XListView extends ListView implements OnScrollListener { private float mLastY = -1; // save event y private Scroller mScroller; // used for scroll back private OnScrollListener mScrollListener; // user's scroll listener // the interface to trigger refresh and load more. private IXListViewListener mListViewListener; // -- header view private XListViewHeader mHeaderView; // header view content, use it to calculate the Header's height. And hide it // when disable pull refresh. private RelativeLayout mHeaderViewContent; private TextView mHeaderTimeView; private int mHeaderViewHeight; // header view's height private boolean mEnablePullRefresh = true; private boolean mPullRefreshing = false; // is refreashing. // -- footer view private XListViewFooter mFooterView; private boolean mEnablePullLoad; private boolean mPullLoading; private boolean mIsFooterReady = false; // total list items, used to detect is at the bottom of listview. private int mTotalItemCount; // for mScroller, scroll back from header or footer. private int mScrollBack; private final static int SCROLLBACK_HEADER = 0; private final static int SCROLLBACK_FOOTER = 1; private final static int SCROLL_DURATION = 400; // scroll back duration private final static int PULL_LOAD_MORE_DELTA = 50; // when pull up >= 50px // at bottom, trigger // load more. private final static float OFFSET_RADIO = 1.8f; // support iOS like pull // feature. /** * @param context */ public XListView(Context context) { super(context); initWithContext(context); } public XListView(Context context, AttributeSet attrs) { super(context, attrs); initWithContext(context); } public XListView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); initWithContext(context); } private void initWithContext(Context context) { mScroller = new Scroller(context, new DecelerateInterpolator()); // XListView need the scroll event, and it will dispatch the event to // user's listener (as a proxy). super.setOnScrollListener(this); // init header view mHeaderView = new XListViewHeader(context); mHeaderViewContent = (RelativeLayout) mHeaderView .findViewById(R.id.xlistview_header_content); mHeaderTimeView = (TextView) mHeaderView .findViewById(R.id.xlistview_header_time); addHeaderView(mHeaderView); // init footer view mFooterView = new XListViewFooter(context); // init header height mHeaderView.getViewTreeObserver().addOnGlobalLayoutListener( new OnGlobalLayoutListener() { @Override public void onGlobalLayout() { mHeaderViewHeight = mHeaderViewContent.getHeight(); getViewTreeObserver() .removeGlobalOnLayoutListener(this); } }); } @Override public void setAdapter(ListAdapter adapter) { // make sure XListViewFooter is the last footer view, and only add once. if (mIsFooterReady == false) { mIsFooterReady = true; addFooterView(mFooterView); } super.setAdapter(adapter); } /** * enable or disable pull down refresh feature. * * @param enable */ public void setPullRefreshEnable(boolean enable) { mEnablePullRefresh = enable; if (!mEnablePullRefresh) { // disable, hide the content mHeaderViewContent.setVisibility(View.INVISIBLE); } else { mHeaderViewContent.setVisibility(View.VISIBLE); } } /** * enable or disable pull up load more feature. * * @param enable */ public void setPullLoadEnable(boolean enable) { mEnablePullLoad = enable; if (!mEnablePullLoad) { mFooterView.hide(); mFooterView.setOnClickListener(null); //make sure "pull up" don't show a line in bottom when listview with one page setFooterDividersEnabled(false); } else { mPullLoading = false; mFooterView.show(); mFooterView.setState(XListViewFooter.STATE_NORMAL); //make sure "pull up" don't show a line in bottom when listview with one page setFooterDividersEnabled(true); // both "pull up" and "click" will invoke load more. mFooterView.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { startLoadMore(); } }); } } /** * stop refresh, reset header view. */ public void stopRefresh() { if (mPullRefreshing == true) { mPullRefreshing = false; resetHeaderHeight(); } } /** * stop load more, reset footer view. */ public void stopLoadMore() { if (mPullLoading == true) { mPullLoading = false; mFooterView.setState(XListViewFooter.STATE_NORMAL); } } /** * set last refresh time * * @param time */ public void setRefreshTime(String time) { mHeaderTimeView.setText(time); } private void invokeOnScrolling() { if (mScrollListener instanceof OnXScrollListener) { OnXScrollListener l = (OnXScrollListener) mScrollListener; l.onXScrolling(this); } } private void updateHeaderHeight(float delta) { mHeaderView.setVisiableHeight((int) delta + mHeaderView.getVisiableHeight()); if (mEnablePullRefresh && !mPullRefreshing) { // 未处于刷新状态,更新箭头 if (mHeaderView.getVisiableHeight() > mHeaderViewHeight) { mHeaderView.setState(XListViewHeader.STATE_READY); } else { mHeaderView.setState(XListViewHeader.STATE_NORMAL); } } setSelection(0); // scroll to top each time } /** * reset header view's height. */ private void resetHeaderHeight() { int height = mHeaderView.getVisiableHeight(); if (height == 0) // not visible. return; // refreshing and header isn't shown fully. do nothing. if (mPullRefreshing && height <= mHeaderViewHeight) { return; } int finalHeight = 0; // default: scroll back to dismiss header. // is refreshing, just scroll back to show all the header. if (mPullRefreshing && height > mHeaderViewHeight) { finalHeight = mHeaderViewHeight; } mScrollBack = SCROLLBACK_HEADER; mScroller.startScroll(0, height, 0, finalHeight - height, SCROLL_DURATION); // trigger computeScroll invalidate(); } private void updateFooterHeight(float delta) { int height = mFooterView.getBottomMargin() + (int) delta; if (mEnablePullLoad && !mPullLoading) { if (height > PULL_LOAD_MORE_DELTA) { // height enough to invoke load // more. mFooterView.setState(XListViewFooter.STATE_READY); } else { mFooterView.setState(XListViewFooter.STATE_NORMAL); } } mFooterView.setBottomMargin(height); // setSelection(mTotalItemCount - 1); // scroll to bottom } private void resetFooterHeight() { int bottomMargin = mFooterView.getBottomMargin(); if (bottomMargin > 0) { mScrollBack = SCROLLBACK_FOOTER; mScroller.startScroll(0, bottomMargin, 0, -bottomMargin, SCROLL_DURATION); invalidate(); } } private void startLoadMore() { mPullLoading = true; mFooterView.setState(XListViewFooter.STATE_LOADING); if (mListViewListener != null) { mListViewListener.onLoadMore(); } } @Override public boolean onTouchEvent(MotionEvent ev) { if (mLastY == -1) { mLastY = ev.getRawY(); } switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: mLastY = ev.getRawY(); break; case MotionEvent.ACTION_MOVE: final float deltaY = ev.getRawY() - mLastY; mLastY = ev.getRawY(); if (getFirstVisiblePosition() == 0 && (mHeaderView.getVisiableHeight() > 0 || deltaY > 0)) { // the first item is showing, header has shown or pull down. updateHeaderHeight(deltaY / OFFSET_RADIO); invokeOnScrolling(); } else if (getLastVisiblePosition() == mTotalItemCount - 1 && (mFooterView.getBottomMargin() > 0 || deltaY < 0)) { // last item, already pulled up or want to pull up. updateFooterHeight(-deltaY / OFFSET_RADIO); } break; default: mLastY = -1; // reset if (getFirstVisiblePosition() == 0) { // invoke refresh if (mEnablePullRefresh && mHeaderView.getVisiableHeight() > mHeaderViewHeight) { mPullRefreshing = true; mHeaderView.setState(XListViewHeader.STATE_REFRESHING); if (mListViewListener != null) { mListViewListener.onRefresh(); } } resetHeaderHeight(); } else if (getLastVisiblePosition() == mTotalItemCount - 1) { // invoke load more. if (mEnablePullLoad && mFooterView.getBottomMargin() > PULL_LOAD_MORE_DELTA && !mPullLoading) { startLoadMore(); } resetFooterHeight(); } break; } return super.onTouchEvent(ev); } @Override public void computeScroll() { if (mScroller.computeScrollOffset()) { if (mScrollBack == SCROLLBACK_HEADER) { mHeaderView.setVisiableHeight(mScroller.getCurrY()); } else { mFooterView.setBottomMargin(mScroller.getCurrY()); } postInvalidate(); invokeOnScrolling(); } super.computeScroll(); } @Override public void setOnScrollListener(OnScrollListener l) { mScrollListener = l; } @Override public void onScrollStateChanged(AbsListView view, int scrollState) { if (mScrollListener != null) { mScrollListener.onScrollStateChanged(view, scrollState); } } @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { // send to user's listener mTotalItemCount = totalItemCount; if (mScrollListener != null) { mScrollListener.onScroll(view, firstVisibleItem, visibleItemCount, totalItemCount); } } public void setXListViewListener(IXListViewListener l) { mListViewListener = l; } /** * you can listen ListView.OnScrollListener or this one. it will invoke * onXScrolling when header/footer scroll back. */ public interface OnXScrollListener extends OnScrollListener { public void onXScrolling(View view); } /** * implements this interface to get refresh/load more event. */ public interface IXListViewListener { public void onRefresh(); public void onLoadMore(); } }2.XListViewFooter
/** * @file XFooterView.java * @create Mar 31, 2012 9:33:43 PM * @author Maxwin * @description XListView's footer */ package animtest.com.example.e531.yuekao_test_demo.view; import android.content.Context; import android.util.AttributeSet; import android.view.LayoutInflater; import android.view.View; import android.widget.LinearLayout; import android.widget.TextView; import animtest.com.example.e531.yuekao_test_demo.R; public class XListViewFooter extends LinearLayout { public final static int STATE_NORMAL = 0; public final static int STATE_READY = 1; public final static int STATE_LOADING = 2; private Context mContext; private View mContentView; private View mProgressBar; private TextView mHintView; public XListViewFooter(Context context) { super(context); initView(context); } public XListViewFooter(Context context, AttributeSet attrs) { super(context, attrs); initView(context); } public void setState(int state) { mHintView.setVisibility(View.INVISIBLE); mProgressBar.setVisibility(View.INVISIBLE); mHintView.setVisibility(View.INVISIBLE); if (state == STATE_READY) { mHintView.setVisibility(View.VISIBLE); mHintView.setText(R.string.xlistview_footer_hint_ready); } else if (state == STATE_LOADING) { mProgressBar.setVisibility(View.VISIBLE); } else { mHintView.setVisibility(View.VISIBLE); mHintView.setText(R.string.xlistview_footer_hint_normal); } } public void setBottomMargin(int height) { if (height < 0) return ; LayoutParams lp = (LayoutParams)mContentView.getLayoutParams(); lp.bottomMargin = height; mContentView.setLayoutParams(lp); } public int getBottomMargin() { LayoutParams lp = (LayoutParams)mContentView.getLayoutParams(); return lp.bottomMargin; } /** * normal status */ public void normal() { mHintView.setVisibility(View.VISIBLE); mProgressBar.setVisibility(View.GONE); } /** * loading status */ public void loading() { mHintView.setVisibility(View.GONE); mProgressBar.setVisibility(View.VISIBLE); } /** * hide footer when disable pull load more */ public void hide() { LayoutParams lp = (LayoutParams)mContentView.getLayoutParams(); lp.height = 0; mContentView.setLayoutParams(lp); } /** * show footer */ public void show() { LayoutParams lp = (LayoutParams)mContentView.getLayoutParams(); lp.height = LayoutParams.WRAP_CONTENT; mContentView.setLayoutParams(lp); } private void initView(Context context) { mContext = context; LinearLayout moreView = (LinearLayout)LayoutInflater.from(mContext).inflate(R.layout.xlistview_footer, null); addView(moreView); moreView.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT)); mContentView = moreView.findViewById(R.id.xlistview_footer_content); mProgressBar = moreView.findViewById(R.id.xlistview_footer_progressbar); mHintView = (TextView)moreView.findViewById(R.id.xlistview_footer_hint_textview); } }3.XlistViewHeader
/** * @file XListViewHeader.java * @create Apr 18, 2012 5:22:27 PM * @author Maxwin * @description XListView's header */ package animtest.com.example.e531.yuekao_test_demo.view; import android.content.Context; import android.util.AttributeSet; import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; import android.view.animation.Animation; import android.view.animation.RotateAnimation; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.ProgressBar; import android.widget.TextView; import animtest.com.example.e531.yuekao_test_demo.R; public class XListViewHeader extends LinearLayout { private LinearLayout mContainer; private ImageView mArrowImageView; private ProgressBar mProgressBar; private TextView mHintTextView; private int mState = STATE_NORMAL; private Animation mRotateUpAnim; private Animation mRotateDownAnim; private final int ROTATE_ANIM_DURATION = 180; public final static int STATE_NORMAL = 0; public final static int STATE_READY = 1; public final static int STATE_REFRESHING = 2; public XListViewHeader(Context context) { super(context); initView(context); } /** * @param context * @param attrs */ public XListViewHeader(Context context, AttributeSet attrs) { super(context, attrs); initView(context); } private void initView(Context context) { // 初始情况,设置下拉刷新view高度为0 LayoutParams lp = new LayoutParams( LayoutParams.FILL_PARENT, 0); mContainer = (LinearLayout) LayoutInflater.from(context).inflate( R.layout.xlistview_header, null); addView(mContainer, lp); setGravity(Gravity.BOTTOM); mArrowImageView = (ImageView)findViewById(R.id.xlistview_header_arrow); mHintTextView = (TextView)findViewById(R.id.xlistview_header_hint_textview); mProgressBar = (ProgressBar)findViewById(R.id.xlistview_header_progressbar); mRotateUpAnim = new RotateAnimation(0.0f, -180.0f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); mRotateUpAnim.setDuration(ROTATE_ANIM_DURATION); mRotateUpAnim.setFillAfter(true); mRotateDownAnim = new RotateAnimation(-180.0f, 0.0f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); mRotateDownAnim.setDuration(ROTATE_ANIM_DURATION); mRotateDownAnim.setFillAfter(true); } public void setState(int state) { if (state == mState) return ; if (state == STATE_REFRESHING) { // 显示进度 mArrowImageView.clearAnimation(); mArrowImageView.setVisibility(View.INVISIBLE); mProgressBar.setVisibility(View.VISIBLE); } else { // 显示箭头图片 mArrowImageView.setVisibility(View.VISIBLE); mProgressBar.setVisibility(View.INVISIBLE); } switch(state){ case STATE_NORMAL: if (mState == STATE_READY) { mArrowImageView.startAnimation(mRotateDownAnim); } if (mState == STATE_REFRESHING) { mArrowImageView.clearAnimation(); } mHintTextView.setText(R.string.xlistview_header_hint_normal); break; case STATE_READY: if (mState != STATE_READY) { mArrowImageView.clearAnimation(); mArrowImageView.startAnimation(mRotateUpAnim); mHintTextView.setText(R.string.xlistview_header_hint_ready); } break; case STATE_REFRESHING: mHintTextView.setText(R.string.xlistview_header_hint_loading); break; default: } mState = state; } public void setVisiableHeight(int height) { if (height < 0) height = 0; LayoutParams lp = (LayoutParams) mContainer .getLayoutParams(); lp.height = height; mContainer.setLayoutParams(lp); } public int getVisiableHeight() { return mContainer.getLayoutParams().height; } }//Drawable用的文件
rb_selector
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_checked="true" android:drawable="@android:color/holo_red_dark"></item> <item android:drawable="@android:color/holo_blue_dark"></item> </selector>
//xml类
1.activity_main.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="match_parent" tools:context="animtest.com.example.e531.yuekao_test_demo.MainActivity"> <android.support.v4.widget.DrawerLayout android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/mydrawer"> <!--主内容区域--> <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent"> <RadioGroup android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:id="@+id/rel_navigate" android:layout_alignParentBottom="true"> <RadioButton android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:text="首页" android:button="@null" android:gravity="center" android:id="@+id/rb_index" android:padding="3dp" android:background="@drawable/rb_selector" android:checked="true"/> <RadioButton android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:text="视频" android:button="@null" android:padding="3dp" android:gravity="center" android:id="@+id/rb_video" android:background="@drawable/rb_selector"/> <RadioButton android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:text="微头条" android:button="@null" android:gravity="center" android:padding="3dp" android:id="@+id/rb_top" android:background="@drawable/rb_selector"/> <RadioButton android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:text="我的" android:padding="3dp" android:button="@null" android:gravity="center" android:id="@+id/rb_me" android:background="@drawable/rb_selector"/> </RadioGroup> <FrameLayout android:layout_width="match_parent" android:layout_height="match_parent" android:layout_above="@id/rel_navigate" android:id="@+id/main_content"></FrameLayout> </RelativeLayout> <RelativeLayout android:layout_width="260dp" android:layout_height="match_parent" android:id="@+id/rel_menu" android:layout_gravity="start" android:background="#550000ff"> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@mipmap/ic_launcher" android:id="@+id/img_title" android:layout_marginBottom="50dp"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="这是侧边栏" android:layout_below="@+id/img_title"/> </RelativeLayout> </android.support.v4.widget.DrawerLayout> </RelativeLayout>2.content_layout.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <animtest.com.example.e531.yuekao_test_demo.view.XListView android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/xlv"> </animtest.com.example.e531.yuekao_test_demo.view.XListView> </LinearLayout>3.index_layout.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <android.support.design.widget.TabLayout android:layout_width="match_parent" android:layout_height="40dp" app:tabGravity="center" app:tabIndicatorColor="@color/colorAccent" app:tabMode="scrollable" app:tabSelectedTextColor="@color/colorPrimaryDark" app:tabTextColor="@color/colorPrimary" android:id="@+id/mytab"></android.support.design.widget.TabLayout> <android.support.v4.view.ViewPager android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/vp"></android.support.v4.view.ViewPager> </LinearLayout>4.item类
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="match_parent"> <ImageView android:layout_width="60dp" android:layout_height="60dp" android:id="@+id/img"/> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/tv_title"/> </LinearLayout>5.me_layout.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" > <TextView android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/tv" android:text="这是我页面" android:textColor="#f00" /> </LinearLayout>6.top_layout.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" > <TextView android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/tv" android:text="这是头条页面" android:textColor="#f00" /> </LinearLayout>7.video_layout.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center"> <TextView android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/tv" android:text="这是视频页面" android:textColor="#f00" /> </LinearLayout>8.xlistview_footer.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content" > <RelativeLayout android:id="@+id/xlistview_footer_content" android:layout_width="fill_parent" android:layout_height="wrap_content" android:padding="10dp" > <ProgressBar android:id="@+id/xlistview_footer_progressbar" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:visibility="invisible" /> <TextView android:id="@+id/xlistview_footer_hint_textview" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:text="@string/xlistview_footer_hint_normal" /> </RelativeLayout> </LinearLayout>9.xlistview_header.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content" android:gravity="bottom" > <RelativeLayout android:id="@+id/xlistview_header_content" android:layout_width="fill_parent" android:layout_height="60dp" > <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:gravity="center" android:orientation="vertical" android:id="@+id/xlistview_header_text"> <TextView android:id="@+id/xlistview_header_hint_textview" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/xlistview_header_hint_normal" /> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="3dp" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/xlistview_header_last_time" android:textSize="12sp" /> <TextView android:id="@+id/xlistview_header_time" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="12sp" /> </LinearLayout> </LinearLayout> <ImageView android:id="@+id/xlistview_header_arrow" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@id/xlistview_header_text" android:layout_centerVertical="true" android:layout_marginLeft="-35dp" android:src="@drawable/xlistview_arrow" /> <ProgressBar android:id="@+id/xlistview_header_progressbar" android:layout_width="30dp" android:layout_height="30dp" android:layout_alignLeft="@id/xlistview_header_text" android:layout_centerVertical="true" android:layout_marginLeft="-40dp" android:visibility="invisible" /> </RelativeLayout> </LinearLayout>