Android编程开发从零开始编写一个轻量级浏览器

目录
  • 返回栈
  • FragmentNavHostBinding
  • 搜索页面暂时放一个EditView
  • MultiStackParentFragment
  • 在里面实现添加窗口
  • 效果图

既然是浏览器,按照国际按理先实现一个多窗口的功能

我打算用ViewPager+Fragment来实现,但仔细想想,这样缺点是十分明显因为要保证Fragment不销毁重建,当viewpager的fragment个数过多,会造成很明显的卡顿,所以先用FragmentManager试试效果

返回栈

多窗口中,每一个窗口都有自己的返回栈

每个返回栈都有自己的 fragmentManager,因此这里使用一个无ui的Fragment作为返回栈的载体

/**
 * @author huangweiliang
 */
class NavHostFragment(var name: String, var windowIndex: Int): Fragment() {
    private lateinit var binding: FragmentNavHostBinding
    private val TAG: String = "NavHostFragment"
    var curSelectFragment: Fragment? = null
    var curChildFragmentManager: FragmentManager? = null
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        //点击返回键,将当前栈的Fragment作出栈处理
        requireActivity().onBackPressedDispatcher.addCallback(this, object : OnBackPressedCallback(true) {
            override fun handleOnBackPressed() {
                isEnabled = childFragmentManager.backStackEntryCount > 0
                if (isEnabled) childFragmentManager.popBackStackImmediate()
//                else requireActivity().onBackPressedDispatcher.onBackPressed()
                else requireActivity().finish()
            }
        })
    }
    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val view = inflater.inflate(R.layout.fragment_nav_host, container, false)
        binding = FragmentNavHostBinding.bind(view)
        return view
    }
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        var tag = name
        //创建窗口的第一个页面,即首页Fragment
        if (childFragmentManager.findFragmentByTag(tag) == null) {

            //这里使用的是childFragmentManager
            childFragmentManager.commitNow {
                val multiChildFragment = MultiChildFragment(name, 1, this@NavHostFragment)
                add(R.id.content, multiChildFragment, tag) //不能使用replace,否则每次返回都要重建
            }
        }
        Log.i(TAG, "$name: onViewCreated")
    }
    override fun onStart() {
        super.onStart()
        Log.i(TAG, "$name: onStart")
    }
    override fun onResume() {
        super.onResume()
        Log.i(TAG, "$name: onResume")
    }
    override fun onPause() {
        super.onPause()
        Log.i(TAG, "$name: onPause")
    }
    override fun onDestroy() {
        super.onDestroy()
        Log.i(TAG, "$name: onDestroy")
    }
}

FragmentNavHostBinding

<androidx.fragment.app.FragmentContainerView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/content"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
</androidx.fragment.app.FragmentContainerView>

搜索页面暂时放一个EditView

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <EditText
        android:id="@+id/ed_search"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginStart="16dp"
        android:layout_marginTop="166dp"
        android:layout_marginEnd="16dp"
        android:padding="12dp"
        android:background="@drawable/gray_rounded_shape"
        android:drawableLeft="@drawable/ic_search_gray_24dp"
        app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

/**
 * @author huangweiliang
 * @date 2021/12/9
 * 多窗口中,具体展示的每一个Fragment
 */
class MultiChildFragment(var name: String, var depth: Int, var hostFragment: Fragment) : Fragment() {
    private lateinit var binding: FragmentMultiChildBinding
    val TAG = "MultiChildFragment"
    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        Log.i(TAG, "$name-$depth: onCreateView")
        val view = inflater.inflate(R.layout.fragment_multi_child, container, false)
        binding = FragmentMultiChildBinding.bind(view)
        //这里做一简单的传参显示当前页面
        binding.edSearch.text.append("$name-$depth")
        init()
        return view
    }
    private fun init() {
    }
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        Log.i(TAG, "$name-$depth: onViewCreated")
    }
    }

再写一个包含多个返回栈的父Fragment

MultiStackParentFragment

class MultiStackParentFragment: Fragment() {
    companion object {
        fun newInstance() = MultiStackParentFragment()
    }
    private lateinit var binding: FragmentMultiStackParentBinding
    private var windowNum: Int = 0
    /**
     * 当前窗口的Index
     */
    private var curWindowIndex: Int = 0
    /**
     * 记录创建的所有窗口对象
     */
    private val mStackList = ArrayList<NavHostFragment>()
    /**
     * 返回栈顺序,存储返回栈id
     */
    private val mOrderStack = ArrayDeque<Int>()
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
    }
    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val view = inflater.inflate(R.layout.fragment_multi_stack_parent, container, false)
        binding = FragmentMultiStackParentBinding.bind(view)
        init()
        return view
    }
    private fun init() {
    }
}

在里面实现添加窗口

childFragmentManager管理着以该Fragment作为父容器的所有子Fragment

private fun addWindow() {
    childFragmentManager.commitNow {
        //NavHostFragment代表一个窗口对象
        val navHostFragment = NavHostFragment("窗口${++windowNum}", windowNum)
        curWindowIndex = windowNum
        mStackList.add(navHostFragment)
        add(R.id.content_fragment, navHostFragment) //添加窗口
    }
    transWindowIndex(curWindowIndex)
}

效果图

以上就是Android编程开发从零开始编写一个轻量级浏览器的详细内容,更多关于Android编程开发轻量级浏览器的资料请关注我们其它相关文章!

(0)

相关推荐

  • Android中调用系统的文件浏览器及自制简单的文件浏览器

    调用系统自带的文件浏览器 这很简单: /** 调用文件选择软件来选择文件 **/ private void showFileChooser() { intent = new Intent(Intent.ACTION_GET_CONTENT); intent.setType("*/*"); intent.addCategory(Intent.CATEGORY_OPENABLE); try { startActivityForResult(Intent.createChooser(inte

  • Android 浏览器的开发实例分享

    本文主要讲解Android浏览器的开发实例,有三部分内容:启动Android默认浏览器.指定浏览器进行访问以及打开本地的html文件.       一.启动Android默认浏览器 Java代码 Intent intent = new Intent(); intent.setAction("android.intent.action.VIEW"); Uri content_url = Uri.parse("http://www.cnblogs.com"); inte

  • Android开发实现浏览器全屏显示功能

    本文实例讲述了Android开发实现浏览器全屏显示功能.分享给大家供大家参考,具体如下: 业务需求:浏览器设置中支持全屏显示的功能. 分析:只需要在设置界面上增加是否全屏的checkBox , 然后 BrowserActivity 中读取这个值, 来设置窗口的 Style. 修改: 1.  修改项目下的 res/xml 文件夹下的 browser_preferences.xml 文件, 添加 <CheckBoxPreference android:key="full_screen"

  • Webview实现android简单的浏览器实例代码

    WebView是Android中一个非常实用的组件,它和Safai.Chrome一样都是基于Webkit网页渲染引擎,可以通过加载HTML数据的方式便捷地展现软件的界面,下面通过本文给大家介绍Webview实现android简单的浏览器实例代码. 实现了浏览器的返回 前进 主页 退出 输入网址的功能 注释的很清楚啦 就不多说了 首先是布局文件 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android&qu

  • Android编程开发从零开始编写一个轻量级浏览器

    目录 返回栈 FragmentNavHostBinding 搜索页面暂时放一个EditView MultiStackParentFragment 在里面实现添加窗口 效果图 既然是浏览器,按照国际按理先实现一个多窗口的功能 我打算用ViewPager+Fragment来实现,但仔细想想,这样缺点是十分明显因为要保证Fragment不销毁重建,当viewpager的fragment个数过多,会造成很明显的卡顿,所以先用FragmentManager试试效果 返回栈 多窗口中,每一个窗口都有自己的返

  • Android编程开发之打开文件的Intent及使用方法

    本文实例讲述了Android编程开发之打开文件的Intent及使用方法.分享给大家供大家参考,具体如下: 在写文件管理系统时会用到各种打开不同格式的文件的需求,由于Android系统默认内置了一些可以打开的系统应用,但还是不能满足需求,比如打开视频文件.word等,需要安装相应的播放软件才可以使用,这时程序会通过Intent查找可以使用的软件实现通过代码打开一个文件需要2部分,一部分是要获取到不同文件的后缀,以便根据需求匹配相应的Intent,另一个就是不同格式的文件打开的Intent不同 1.

  • Android编程开发实现多线程断点续传下载器实例

    本文实例讲述了Android编程开发实现多线程断点续传下载器.分享给大家供大家参考,具体如下: 使用多线程断点续传下载器在下载的时候多个线程并发可以占用服务器端更多资源,从而加快下载速度,在下载过程中记录每个线程已拷贝数据的数量,如果下载中断,比如无信号断线.电量不足等情况下,这就需要使用到断点续传功能,下次启动时从记录位置继续下载,可避免重复部分的下载.这里采用数据库来记录下载的进度. 效果图:   断点续传 1.断点续传需要在下载过程中记录每条线程的下载进度 2.每次下载开始之前先读取数据库

  • Android编程开发实现带进度条和百分比的多线程下载

    本文实例讲述了Android编程开发实现带进度条和百分比的多线程下载.分享给大家供大家参考,具体如下: 继上一篇<java多线程下载实例详解>之后,可以将它移植到我们的安卓中来,下面是具体实现源码: DownActivity.java: package com.example.downloads; import java.io.File; import java.io.IOException; import java.io.RandomAccessFile; import java.net.H

  • Android编程开发中ListView的常见用法分析

    本文实例讲述了Android编程开发中ListView的常见用法.分享给大家供大家参考,具体如下: 一.ListView的使用步骤 ListView的使用通常有以下三个要素: (1)ListView中每个条目的布局; (2)填充进入ListView中的内容; (3)将内容与页面进行整合的Adapter. 因此,使用ListView也通常有以下三个步骤: (1)创建ListView条目的布局文件(或使用Android SDK提供的布局); (2)创建填充进入ListView中的内容,如字符串.图片

  • Android编程开发音乐播放器实例

    本文实例讲述了Android编程开发音乐播放器,分享给大家供大家参考,具体如下: 音乐播放器中综合了以下内容: SeekBar.ListView.广播接收者(以代码的形式注册Receiver).系统服务.MediaPlayer 实现的功能: 1.暂停/播放.下一首/上一首,点击某一首时播放 2.支持拖动进度条快进 3.列表排序 4.来电话时,停止播放,挂断后继续播放 5.可在后台播放 效果图: 界面: main.xml: <?xml version="1.0" encoding=

  • Android编程实现的超炫图片浏览器

    本文实例讲述了Android编程实现的超炫图片浏览器.分享给大家供大家参考,具体如下: 使用过Android自带的gallery组件的人都知道,gallery实现的效果就是拖动浏览一组图片,相比iphone里也是用于拖动浏览图片的coverflow,显然逊色不少.实际上,可以通过扩展gallery,通过伪3D变换可以基本实现coverflow的效果.本文通过源代码解析这一功能的实现.具体代码作用可参照注释. 最终实现效果如下: 要使用gallery,我们必须首先给其指定一个adapter.在这里

  • Android编程开发之多点触摸(Multitouch)实现方法

    本文实例讲述了Android编程开发之多点触摸(Multitouch)实现方法.分享给大家供大家参考,具体如下: 如果您对开发多点触摸程序感兴趣的话,那么本文将是一个很好的开始,android应用程序开发中,多点触摸不是那么遥不可及,实现起来也很简单,本例只需要两个类就能实现多点触摸. 首先来看看我们的视图类MTView.java: package com.ideasandroid.demo; import android.content.Context; import android.grap

  • Android编程开发之性能优化技巧总结

    本文详细总结了Android编程开发之性能优化技巧.分享给大家供大家参考,具体如下: 1.http用gzip压缩,设置连接超时时间和响应超时时间 http请求按照业务需求,分为是否可以缓存和不可缓存,那么在无网络的环境中,仍然通过缓存的httpresponse浏览部分数据,实现离线阅读. 2.listview 性能优化 1).复用convertView 在getItemView中,判断convertView是否为空,如果不为空,可复用.如果couvertview中的view需要添加listern

  • Android编程开发ScrollView中ViewPager无法正常滑动问题解决方法

    本文实例讲述了Android编程开发ScrollView中ViewPager无法正常滑动问题解决方法.分享给大家供大家参考,具体如下: 这里主要介绍如何解决ViewPager在ScrollView中滑动经常失效.无法正常滑动问题. 解决方法只需要在接近水平滚动时ScrollView不处理事件而交由其子View(即这里的ViewPager)处理即可,重写ScrollView的onInterceptTouchEvent函数,如下: package cc.newnews.view; import an

随机推荐