接着上回,我们继续分说下面步骤。
用户登录后,映入眼帘的就是我们实现阅读器的主要三个界面,分别是书架、感悟、分类。
首先这三个界面的切换是通过Fragment实现的底部导航:
activity_main_login.xml:
这里的menu是在res文件夹下创建的menu文件夹,具体存放图标和文字
menu_main.xml:
接下来是java文件MainLogin:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_login);
viewPager=findViewById(R.id.viewPager);
bottomNavigationView=findViewById(R.id.bottomNavigationView);
//初始化fragments数组
list=new ArrayList();
list.add(new LoginFragment1());
list.add(new LoginFragment2());
list.add(new LoginFragment3());
//设置底部导航点击和不点击时颜色
Resources resource = getResources();
@SuppressLint("ResourceType")
ColorStateList csl = resource.getColorStateList(R.drawable.fgbtn);
bottomNavigationView.setItemTextColor(csl);
viewPager.setAdapter(new MyAdapter(getSupportFragmentManager(),list));
//点击底部导航项,显示对应的页面
bottomNavigationView.setOnNavigationItemSelectedListener(
new BottomNavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
switch (item.getItemId()){
case R.id.item1:
viewPager.setCurrentItem(0);
break;
case R.id.item2:
viewPager.setCurrentItem(1);
break;
case R.id.item3:
viewPager.setCurrentItem(2);
break;
}
return true;
}
});
//页面左右滑动时,让底部的导航项和显示的页面保持一致
viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
if(menuItem==null){
menuItem=bottomNavigationView.getMenu().getItem(0);
}
//将上次的选择设置为false,等待下次的选择
menuItem.setChecked(false);
menuItem=bottomNavigationView.getMenu().getItem(position);
menuItem.setChecked(true);
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
}
//作为fragment的适配器
private class MyAdapter extends FragmentPagerAdapter
{
List list;
public MyAdapter(@NonNull FragmentManager fm, List list) {
super(fm);
this.list=list;
}
@NonNull
@Override
public Fragment getItem(int position)
{
return (Fragment) list.get(position);
}
@Override
public int getCount()
{
return list.size();
}
}
}
现在我们的底部导航已经建好了,接下来需要我们新建三个fragment页面,分别实现书架、感悟、分类三个部分。
首先是书架部分,先上图看看效果:
fragment_login1.xml:
在这里说明一下,页面的顶部本质是一个TextView控件,但文字是可以横向滚动的,所以得自己写一个基于TextView的子类。
java文件MarqueTextView:
public class MarqueTextView extends androidx.appcompat.widget.AppCompatTextView {
public MarqueTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public MarqueTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MarqueTextView(Context context) {
super(context);
}
@Override
public boolean isFocused() {
//就是把这里返回true即可
return true;
}
}
然后是实现书架这一部分的java文件LoginFragment1:
public class LoginFragment1 extends Fragment implements AdapterView.OnItemClickListener{
//变量名注册
ListView listView;
SimpleAdapter simpleAdapter;
public View onCreateView
(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_login1, container, false);
//id注册
listView = view.findViewById(R.id.lg3_listView);
MarqueTextView as = view.findViewById(R.id.mtv);
simpleAdapter = new SimpleAdapter(getActivity(),getData(),R.layout.item,
new String[]{"title","image"},new int[]{R.id.item_tv,R.id.item_image});
//设置适配器监听器
listView.setAdapter(simpleAdapter);
listView.setOnItemClickListener(this);
//将文件由assets转移到手机空间
copyFilesFromAssets(getActivity(),"ml","/data/data/com.example.ebook/files");
as.setText(load());
return view;
}
//设置listview图文
private List
其实现在看来当时写的还是非常简单的,在书架展示这一块是靠代码后台输入文字介绍,以及用简单地Switch现实跳转,换成现在有更好的解决方式。不过这是后话,我想能力的提升也是循序渐进的。我还是来解释一些核心的代码。
书的内容是以txt格式存放在之前提到的asset文件夹里面,copyFilesFromAssets函数便是实现对asset文件内容的读取。这样就实现了文件可以随着代码一起保存并放到手机上,不用创建数据库(现在觉得创建了数据库实现的功能可能可以更加完善)是一种投机取巧的方式
这里的适配器simpleAdapter里的item:
当用户点进一本书后会看到类似界面:
activity_read_book.xml:
java文件ReadBook:
public class ReadBook extends AppCompatActivity {
String txt;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_read_book);
Intent intent=getIntent();
txt=intent.getStringExtra("extra");
Log.d("ReadBook",txt);
TextView sb = findViewById(R.id.sd);
sb.setMovementMethod(ScrollingMovementMethod.getInstance());
sb.setSelected(true);
sb.setText(load());
}
//获取手机空间中的txt文件
public String load() {
FileInputStream in = null;
BufferedReader reader = null;
StringBuilder content = new StringBuilder();
try {
in = openFileInput(txt);
reader = new BufferedReader(new InputStreamReader(in));
String line = "";
while ((line = reader.readLine()) != null) {
content.append("n");
content.append(line);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return content.toString();
}
}
这里的Log是用来实现两个活动直接的信息传递,load函数就是基本的读取txt文件操作了。
到此为止作为一个阅读器最重要的阅读功能就可以实现了,接下来的感悟和分类,均使用到了数据库,待下回分解。



