由于这个APP的需求分析中有一个可以导入本地书籍的功能,这个功能放在哪里?看了宜搜小说这些阅读APP,它们都是模仿微信右上角点击弹出一个小的弹出框,然后进行选项的选择。大题图如下:
实现这个功能采用的方式是使用PopupWindow。至于每本书籍显示则是采用ListView。
在进行实现PopupWindwo的功能前,要实现弹出后弹出框的界面布局,这里新建一个布局文件的xml。只有先建好,后续工作才能进行。
因为这个界面的顶部导航栏和其他三个不同,所以这里要写的代码都是在第一个类的Fragement,我取得名字是books。在这里PopupWindow不能直接使用,需要使用一个类来集成它然后重新构造一个实列化方法,以便到达我们想要的界面。
//定义右上角弹窗类
public class BookWindow extends PopupWindow{
public BookWindow(Context context){
super(context);
setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);//设置弹出框的高度
setWidth(280);//设置弹出框的高度
setOutsideTouchable(true);//设置是否可以点击弹出框外面而使弹出框消失
setFocusable(false);//设置是否一开始就显示弹出框
setBackgroundDrawable(new ColorDrawable(getResources().getColor(R.color.popupWindow)));//设置背景颜色
View contentView = LayoutInflater.from(context).inflate(R.layout.book_popupwindow,
null, false);//设置背景的布局文件
setContentView(contentView);
}
}
BookWindow的类创建以后,需要获取父层的contentView的大小,不然可能会使弹出框的大小不像我们想象的样子。
// 获取contentView的大小
@SuppressWarnings("ResourceType")
private static int makeDropDownMeasureSpec(int measureSpec){
int mode;
if (measureSpec == ViewGroup.LayoutParams.WRAP_CONTENT) {
mode = View.MeasureSpec.UNSPECIFIED;
} else {
mode = View.MeasureSpec.EXACTLY;
}
return View.MeasureSpec.makeMeasureSpec(View.MeasureSpec.getSize(measureSpec), mode);
}
对于弹出框的基本声明已经完成,接下来就需要进行一定的设置。
// 初始化右上角弹出框
public void initPopupWindow(){
BookWindow mWindow =new BookWindow(this.getContext());
View contentView=mWindow.getContentView();
contentView.measure(makeDropDownMeasureSpec(mWindow.getWidth()),makeDropDownMeasureSpec(mWindow.getHeight()));
int offsetX = Math.abs(mWindow.getContentView().getMeasuredWidth()-category.getWidth()) / 2;
int offsetY = 20;
TextView textView1=(TextView)contentView.findViewById(R.id.exchang_layout);
TextView textView2=(TextView)contentView.findViewById(R.id.import_book);
TextView textView3=(TextView)contentView.findViewById(R.id.edit_book);
textView1.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v){
Log.i("111", "九宫格显示");
}
});
textView2.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v){
Log.i("222", "导入本地书籍");
}
});
textView3.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v){
Log.i("333","编辑书架");
}
});
PopupWindowCompat.showAsDropDown(mWindow, category, offsetX, offsetY, Gravity.START);
}
这样基本上就完成了,但是不要忘记将上面的这个初始化方法绑定到右上角的那个触动按钮的点击事件中。
在上图中是多个书籍信息显示,在这里面是使用了BaseAdapter来做的适配器,此外在这个里面使用了ViewHolder类,之所以使用ViewHolder的方法是为了进一步的优化ListView减少耗时的作用,可以将要加载的子View放在ViewHolder类,当第一次创建convetView时将这些控件找出,在第二次重用convertView时就可以直接通过convertView中的getTag()方法获得控件。具体代码如下:
//listView的适配器
class MyBaseAdapter extends BaseAdapter{
@Override
public int getCount(){
return names.length;
}
@Override
public Object getItem(int position){
return names[position];
}
@Override
public long getItemId(int position){
return position;
}
@Override
public View getView(int position,View convertView,ViewGroup parent){
ViewHolder holder;
if(convertView==null){
convertView= LayoutInflater.from(context).inflate(R.layout.book_booklist,parent,false);
holder=new ViewHolder();
holder.smartImageView=(SmartImageView)convertView.findViewById(R.id.item_image);
holder.TextView1=(TextView)convertView.findViewById(R.id.book_title);
holder.TextView2=(TextView)convertView.findViewById(R.id.book_author);
holder.TextView3=(TextView)convertView.findViewById(R.id.book_source);
holder.TextView4=(TextView)convertView.findViewById(R.id.book_info);
holder.TextView5=(TextView)convertView.findViewById(R.id.book_readDate);
convertView.setTag(holder);
}else{
holder=(ViewHolder)convertView.getTag();
}
// holder.mTextView.setText(temp[position]);
// Article temp=articleLists.get(position);
// holder.smartImageView.setImageUrl(temp.getImage());
holder.TextView1.setText(names[position]);
holder.TextView2.setText("江南");
holder.TextView3.setText("本地书籍");
holder.TextView4.setText("899章/992章");
holder.TextView5.setText("10小时前看过");
return convertView;
}
class ViewHolder{
SmartImageView smartImageView;
TextView TextView1;
TextView TextView2;
TextView TextView3;
TextView TextView4;
TextView TextView5;
}
}
然后在最开始的地方,获取ListView并设置适配器为上面类的一个对象。这里不得不说声,因为这个地方是在Fragement里面所写的,所以和Activity里面的有些不同,在上面的getView()方法中的View类型的参数convertView和convertView获取时用的一个参数context。这两个必须在Fragement的onCreateCiew的方法中进行赋值,这个值其实最外层的Activity,即在这个方法使用getActivity()赋值。只有这样才能进行接下来的操作。
到此就完成了书库的一部分界面(可能后面会有所修改)。