项目实战①—高仿知乎日报(2)—>使用pullrefesh+Slidingmenu+自定义组件写主布局


①项目架构

其实这个布局我一开始没想过做侧滑菜单,最后其实用我自己的框架 已经把基本页面做完了,但是,最后上拉加载更多卡住了,最后李老师帮我把架构重构了一下,最后得以完成感谢李老师

主布局相信大家都看得出来 pullrefesh 加下滑菜单 我再想我该怎么写这一篇文章呢,因为这涉及到自定义的类,抽取到了一个类了,我觉得还是一个一个知识点讲吧


② 侧滑菜单Slidingmenu


一 什么是SlidingMenu
SlidingMenu是一种比较新的设置界面或配置界面的效果,在主界面左滑或者右滑出现设置界面效果,能方便的进行各种操作。很多优秀的应用都采用了这种界面方案,像facebook、人人网、everynote、Google+等等
二 配置SlidingMenu
下载地址
侧滑菜单 :SlidingMenu:https://github.com/jfeinstein10/SlidingMenu 
依赖包 :   ActionBarSherlock:https://github.com/JakeWharton/ActionBarSherlock

解决错误

1.重新配置Library链接

2.删除SlidingMenu类库中自带的support-v4.jar

3.配置SlidingMenu引用ActionBarSherlock类库

4.修改SlidingMenu类库下SlidingFragmentActivity继承SherlockFragmentActivity

常用属性

设置左滑菜单                                    menu.setMode(SlidingMenu.LEFT);
设置滑动的模式                                menu.setTouchModeAbove(SlidingMenu.TOUCHMODE_FULLSCREEN);
设置阴影                                            menu.setShadowDrawable(R.drawable.shadow);
设置阴影的宽度                                menu.setShadowWidthRes(R.dimen.shadow_width);
划出时主页面显示的剩余宽度        menu.setBehindOffsetRes(R.dimen.slidingmenu_offset);
菜单的宽度                                        menu.setBehindWidth(400);
滑动时的渐变程度                            menu.setFadeDegree(0.35f);
附加在Activity上                                menu.attachToActivity(this, SlidingMenu.SLIDING_CONTENT);
设置menu的布局文件                     menu.setMenu(R.layout.menu_layout);
动态断定主动封闭或开启                menu.toggle();
显示                                                    menu.showMenu();
显示内容                                            menu.showContent();
监听器                                                打开 menu.setOnOpenListener(onOpenListener);   关闭menu.OnClosedListener(OnClosedListener);
设置左右菜单     设置右侧阴影       sm.setSecondaryShadowDrawable(R.drawable.shadowright);
设置右侧菜单布局                            sm.setSecondaryMenu(R.layout.menu_frame2);  

看不下去了吧 还是直接看图片吧





三应用SlidingMenu
1.Activity实现SlidingMenu
// 实例化一个SlidingMenu
slidingMenu = new SlidingMenu(this);
// 设置为左侧滑动模式
slidingMenu.setMode(SlidingMenu.LEFT);
// 设置全屏触发滑动
slidingMenu.setTouchModeAbove(SlidingMenu.TOUCHMODE_FULLSCREEN);
// 设置阴影效果
slidingMenu.setShadowDrawable(R.drawable.shadow);
// 设置阴影宽度
slidingMenu.setShadowWidth(3);
// 设置滑出时主页面显示的剩余宽度
slidingMenu.setBehindOffset(10);
// 设置滑出的宽度
slidingMenu.setBehindWidth(350);
// 设置淡入淡出效果
slidingMenu.setFadeDegree(0.35f);
// 设置依附于Activity
slidingMenu.attachToActivity(this, SlidingMenu.SLIDING_CONTENT);
// 设置左侧滑出菜单的布局
slidingMenu.setMenu(R.layout.slidingmenu_test);

2.SlidingMenu里的点击事务
因为SlidingMenu已经被包含在了Activity中了,所以直接findViewById(id),拿到view之后就可以进行响应的处理


其实从Slidingmenu 源码中可以看出来,他一般是和ActionBarSherlock ,Fragment  所以主布局就是 就是一个标题+Fragment  SO--------
我用了一个Framelayout+自定义title
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    
    <com.qf.teach.project.zhihudaily.custom.CustomTitle
        android:id="@+id/custom_title"
        android:layout_width="match_parent"
        android:layout_height="60dp" />

    <FrameLayout
        android:id="@+id/fl_content"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</LinearLayout>

四 自定义title
不知道大家还记不记得自定义,首先你要继承一个一样东西,然后重写 带两个参数的构造方法 将布局填充进去,然后定义一个你需要的方法,这里既然我们需要一个设置title文字的方法
package com.qf.teach.project.zhihudaily.custom;

import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.widget.FrameLayout;
import android.widget.TextView;

import com.qf.teach.project.zhihudaily.R;

/**
 * 自定义标题
 * @author Lusifer
 *
 * 2014年12月1日下午2:32:33
 */
public class CustomTitle extends FrameLayout {
	private TextView txTitle;

	public CustomTitle(Context context, AttributeSet attrs) {
		super(context, attrs);
		
		// 绑定布局
		LayoutInflater.from(context).inflate(R.layout.custom_title, this);
		
		initView();
	}

	private void initView() {
		txTitle = (TextView) findViewById(R.id.tx_title);
	}
	
	public void setTitle(String title) {
		txTitle.setText(title);
	}

}

回到java代码

③ 初始化界面

既然要用到Fragment 所以我们activity 就继承了 FragmentActivity  用Fragment去取代其中的Framelayout

一初始化组件

	/**
	 * 初始化界面(Fragment)
	 */
	private void initView() {
		cTitle = (CustomTitle) findViewById(R.id.custom_title);
		cTitle.setTitle("首页");
		cTitle.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
//				slidingmenu动态断定主动封闭或开启
				menu.toggle();
			}
		});
		
		FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
		fragmentTransaction.replace(R.id.fl_content, MainFragment.newInstance());
		fragmentTransaction.commit();
	}

二初始化Slidingmenu 
相信经过上面讲解Slidingmenu 大家应该都知道怎么应用Slidingmenu 了,先看Slidingmenu的界面吧,其实也是要加载数据的 




其中也就是一个listview需要获取列表的数据
	/**
	 * 初始化SlidingMenu
	 */
	private void initSlidingMenu() {
		mQueue = Volley.newRequestQueue(getApplicationContext());
		
		// 菜单
		menu = new SlidingMenu(this);
		menu.setMode(SlidingMenu.LEFT);
        menu.setTouchModeAbove(SlidingMenu.TOUCHMODE_MARGIN);
        menu.setShadowWidth(10);
        menu.setShadowDrawable(R.drawable.shadow);
        menu.setBehindOffset(100);
        menu.setFadeDegree(0.35f);
        menu.attachToActivity(this, SlidingMenu.SLIDING_CONTENT);
        menu.setMenu(R.layout.sliding_left);
        
        // 主题
        adapter = new MyBaseAdapter();
        //listview加载数据
        lvTheme = (ListView) findViewById(R.id.lv_theme);
        lvTheme.setOnItemClickListener(this);
        lvTheme.setAdapter(adapter);
        mQueue.add(new JsonObjectRequest(Method.GET, API.getThemesUrl(), null, this, null));
	}


上面菜单那一段代码 相信大家都懂,下面那个主题,也就是Slidingmenu 里面的东西 要进行联网将数据拿下来 填充到Baseadapter里面去
(1)用volly进行联网请求数据拿到json

  注意到上面的这两句话,其实真正的URL已经不在java代码里了,而在jni里面,就算反编译也得不到..............

mQueue = Volley.newRequestQueue(getApplicationContext());
mQueue.add(new JsonObjectRequest(Method.GET, API.getThemesUrl(), null, this, null));

然后让我们看看json结构,最外层是一个大括号,所以vally的用jsonobject  相信大家json解析还是会的



根据 json结构先建立 实体类 里面有两个数组 SO
package com.qf.teach.project.zhihudaily.entity;

import java.util.List;

public class Theme {
	private int limit;
	private List<ThemeOther> others;

	public int getLimit() {
		return limit;
	}

	public void setLimit(int limit) {
		this.limit = limit;
	}

	public List<ThemeOther> getOthers() {
		return others;
	}

	public void setOthers(List<ThemeOther> others) {
		this.others = others;
	}
}

package com.qf.teach.project.zhihudaily.entity;

public class ThemeOther {
	private int color;
	private String image;
	private String description;
	private long id;
	private String name;

	public int getColor() {
		return color;
	}

	public void setColor(int color) {
		this.color = color;
	}

	public String getImage() {
		return image;
	}

	public void setImage(String image) {
		this.image = image;
	}

	public String getDescription() {
		return description;
	}

	public void setDescription(String description) {
		this.description = description;
	}

	public long getId() {
		return id;
	}

	public void setId(long id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
}

	/* -------------------- 网络请求 -------------------- */

	@Override
	public void onResponse(JSONObject response) {
		theme = new Theme();
		
		try {
			theme.setLimit(response.getInt("limit"));
			
			// 解析Others
			JSONArray jsonArray = response.getJSONArray("others");
			if (jsonArray != null && jsonArray.length() > 0) {
				List<ThemeOther> others = new ArrayList<ThemeOther>();
				
				// 手动增加首页
				ThemeOther other = new ThemeOther();
				other.setName("首页");
				others.add(other);
				
				// 解析
				for (int i = 0 ; i < jsonArray.length() ; i++) {
					JSONObject obj = jsonArray.getJSONObject(i);
					other = new ThemeOther();
					other.setColor(obj.getInt("color"));
					other.setDescription(obj.getString("description"));
					other.setId(obj.getLong("id"));
					other.setImage(obj.getString("image"));
					other.setName(obj.getString("name"));
					others.add(other);
				}
				
				theme.setOthers(others);
				
				adapter.notifyDataSetChanged();
			}
		} catch (JSONException e) {
			e.printStackTrace();
		}
	}
	
	/* -------------------- 网络请求 -------------------- */

(2)实例化Adapter并进行填充数据
adapter 其实就写在mainactivity类中,所以可以省略了传值问题,其中也对Listview 进行了优化比如复用convertView 减少系统findByid的次数 

/**
	 * ThemeAdapter
	 * @author Lusifer
	 *
	 * 2014年12月4日下午2:11:55
	 */
	class MyBaseAdapter extends BaseAdapter {
		private ViewHolder viewHolder;

		@Override
		public int getCount() {
			return theme == null ? 0 : theme.getOthers().size();
		}

		@Override
		public Object getItem(int position) {
			return theme.getOthers().get(position);
		}

		@Override
		public long getItemId(int position) {
			return position;
		}

		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			if (convertView == null) {
				convertView = LayoutInflater.from(MainActivity.this).inflate(R.layout.list_theme, parent, false);
				
				viewHolder = new ViewHolder();
				viewHolder.txTitle = (TextView) convertView.findViewById(R.id.tx_title);
				
				convertView.setTag(viewHolder);
			} else {
				viewHolder = (ViewHolder) convertView.getTag();
			}
			
			ThemeOther other = theme.getOthers().get(position);
			viewHolder.txTitle.setText(other.getName());
			
			return convertView;
		}
		
		class ViewHolder {
			public TextView txTitle;
		}
		
	}

OK 到这里 Slidingmenu里面的数据 也就填充上去了  

End

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值