欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Android手册类应用开发框架

程序员文章站 2024-03-24 15:26:58
...

1.前段时间,一时兴起想做一个手册类应用,无奈,想学着做,结果完全没找到相关的参考,只好自己动手研究

2.话不多说,直接先看效果

Android手册类应用开发框架

3.很明显,里面内容无关,其实主要思路也很简单,使一个侧滑栏,即为android自带的 AndroidDrawerLayout实现,同时在侧滑菜单中使用下拉列表ExpandableListView,主界面使用一个WebView承载所有关于内容的html,根据下拉列表的点击项动态改变WebView的内容,这样就完成了基本的功能

下面给出其中用到的控件的详细使用参考

1.AndroidDrawerLayout+fragment布局实现左右侧滑
2.Android之侧滑菜单DrawerLayout的使用
3.DrawerLayout侧滑详解
4.Android中ExpandableListView的使用

5.下面给出一部分简单的代码简要介绍,写的有点乱

ublic class MainActivity extends AppCompatActivity {

    private Map<String, List<String>> dataset = new HashMap<>();
    private String[] parentList = new String[]{"first", "second", "third"};
    private List<String> childrenList1 = new ArrayList<>();
    private List<String> childrenList2 = new ArrayList<>();
    private List<String> childrenList3 = new ArrayList<>();

    private DrawerLayout drawer;
    private TextView tv;
    private MyExpandableListViewAdapter adapter;
    private ExpandableListView listview;
    private Toolbar toolbar;
    private ActionBarDrawerToggle mDrawerToggle;
    private WebView mWebView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initViews();
        initialData();
    }

    private void initViews(){
        mWebView = (WebView) findViewById(R.id.webview);
        initWebSettings();
        mWebView.loadUrl("file:///android_asset/0.html");
        toolbar = (Toolbar) findViewById(R.id.tl_custom);
        toolbar.setTitle("Toolbar");//设置Toolbar标题
        toolbar.setBackgroundColor(Color.parseColor("#f0f0f0"));
        toolbar.setTitleTextColor(Color.parseColor("#000000")); //设置标题颜色
        setSupportActionBar(toolbar);
        getSupportActionBar().setHomeButtonEnabled(true); //设置返回键可用
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);




        tv = (TextView) findViewById(R.id.text);
        drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
        listview = (ExpandableListView) findViewById(R.id.expandablelistview);
        adapter = new MyExpandableListViewAdapter();
        listview.setAdapter(adapter);
        listview.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
            @Override
            public boolean onChildClick(ExpandableListView expandableListView, View view,
                                        int parentPos, int childPos, long l) {
                tv.setText(dataset.get(parentList[parentPos]).get(childPos)+"!");
                showDrawerLayout();
                mWebView.loadUrl("file:///android_asset/"+(parentPos*parentList.length+childPos)+".html");
                return true;
            }
        });



        mDrawerToggle = new ActionBarDrawerToggle(this, drawer, toolbar, R.string.open, R.string.close) {
            @Override
            public void onDrawerOpened(View drawerView) {
                super.onDrawerOpened(drawerView);
                //mAnimationDrawable.stop();
            }
            @Override
            public void onDrawerClosed(View drawerView) {
                super.onDrawerClosed(drawerView);
                //mAnimationDrawable.start();
            }
        };
        mDrawerToggle.syncState();
        drawer.setDrawerListener(mDrawerToggle);
    }

    private void initialData() {
        childrenList1.add(parentList[0] + "-" + "first");
        childrenList1.add(parentList[0] + "-" + "second");
        childrenList1.add(parentList[0] + "-" + "third");
        childrenList2.add(parentList[1] + "-" + "first");
        childrenList2.add(parentList[1] + "-" + "second");
        childrenList2.add(parentList[1] + "-" + "third");
        childrenList3.add(parentList[2] + "-" + "first");
        childrenList3.add(parentList[2] + "-" + "second");
        childrenList3.add(parentList[2] + "-" + "third");
        dataset.put(parentList[0], childrenList1);
        dataset.put(parentList[1], childrenList2);
        dataset.put(parentList[2], childrenList3);
    }
    private void initWebSettings() {
        WebSettings settings = mWebView.getSettings();
        settings.setSupportZoom(false);

        settings.setRenderPriority(WebSettings.RenderPriority.HIGH);
        settings.setJavaScriptEnabled(true);
        settings.setUseWideViewPort(false);
        settings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NARROW_COLUMNS);

        settings.setCacheMode(WebSettings.LOAD_DEFAULT);
        settings.setDomStorageEnabled(true);
        settings.setDatabaseEnabled(true);
    }
    private void showDrawerLayout() {
        if (!drawer.isDrawerOpen(Gravity.LEFT)) {
            drawer.openDrawer(Gravity.LEFT);
        } else {
            drawer.closeDrawer(Gravity.LEFT);
        }
    }
    @Override
    public void onBackPressed() {
        if (drawer.isDrawerOpen(GravityCompat.START)) {
            drawer.closeDrawer(GravityCompat.START);
        } else {
            super.onBackPressed();
        }
    }

    public class MyExpandableListViewAdapter extends BaseExpandableListAdapter {
        //  获得某个父项的某个子项
        @Override
        public Object getChild(int parentPos, int childPos) {
            return dataset.get(parentList[parentPos]).get(childPos);
        }

        //  获得父项的数量
        @Override
        public int getGroupCount() {
            return dataset.size();
        }

        //  获得某个父项的子项数目
        @Override
        public int getChildrenCount(int parentPos) {
            return dataset.get(parentList[parentPos]).size();
        }

        //  获得某个父项
        @Override
        public Object getGroup(int parentPos) {
            return dataset.get(parentList[parentPos]);
        }

        //  获得某个父项的id
        @Override
        public long getGroupId(int parentPos) {
            return parentPos;
        }

        //  获得某个父项的某个子项的id
        @Override
        public long getChildId(int parentPos, int childPos) {
            return childPos;
        }

        //  按函数的名字来理解应该是是否具有稳定的id,这个方法目前一直都是返回false,没有去改动过
        @Override
        public boolean hasStableIds() {
            return false;
        }

        //  获得父项显示的view
        //View中的setTag(Onbect)表示给View添加一个格外的数据,以后可以用getTag()将这个数据取出来。
        //可以用在多个Button添加一个监听器,每个Button都设置不同的setTag。这个监听器就通过getTag来分辨是哪个Button 被按下
        @Override
        public View getGroupView(int parentPos, boolean b, View view, ViewGroup viewGroup) {
            if (view == null) {
                LayoutInflater inflater = (LayoutInflater)MainActivity
                        .this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                view = inflater.inflate(R.layout.parent_item, null);
            }
            view.setTag(R.layout.parent_item, parentPos);
            view.setTag(R.layout.child_item, -1);
            TextView text = (TextView) view.findViewById(R.id.parent_title);
            text.setText(parentList[parentPos]);
            return view;
        }

        //  获得子项显示的view
        @Override
        public View getChildView(int parentPos, int childPos, boolean b, View view, ViewGroup viewGroup) {
            if (view == null) {
                LayoutInflater inflater = (LayoutInflater) MainActivity
                        .this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                view = inflater.inflate(R.layout.child_item, null);
            }
            view.setTag(R.layout.parent_item, parentPos);
            view.setTag(R.layout.child_item, childPos);
            TextView text = (TextView) view.findViewById(R.id.child_title);
            text.setText(dataset.get(parentList[parentPos]).get(childPos));
            return view;
        }

        //  子项是否可选中,如果需要设置子项的点击事件,需要返回true
        @Override
        public boolean isChildSelectable(int i, int i1) {
            return true;
        }
    }
}

6.其实吧,上述使用的控件以前也没见过,笔者索性找了一个简单的手册应用,然后演练了一把apk反编译,果然就看到了源码,假装记录一下

apk反编译主要有三个工具
(1).apktool 作用:资源文件获取,可以提取出图片文件和布局文件进行使用查看
(2).dex2jar 将apk中的dex反编译成Java源码(classes.dex转化成jar文件)
(3).jd-gui 作用:查看APK中classes.dex转化成出的jar文件,即源码文件

笔者就是将dex转为jar后看到了部分源码,给了笔者一点启发,只是为了学习

具体apk反编译请参考这篇博客–》Android APK反编译就这么简单 详解(附图)

7.最后给出github地址,欢迎star,笔者能力,不足之处,欢迎留言讨论

我的github地址