AndroidStudio-学习笔记之多级目录功能的设计与开发

news2024/11/17 16:04:10

多级目录功能的设计与开发

  • 演示效果
  • 需求描述
  • 开发预计
    • 前端
    • 后端
  • 前端开发
    • 多级目录的UI小框架
    • 前端xml
    • 前端代码---本地demo版
    • 前端代码---服务器版
      • 逻辑说明
  • 后端开发
    • 表设计
    • 书写接口

演示效果

在这里插入图片描述

需求描述

根据需求,为用户展示多级目录(目前设计的为4级目录),并在选择了指定目录后显示详情页面,供用户点赞,查看,上传,标记等操作

开发预计

前端

  1. 每一页显示一个层级/目录的内容,包括标题,img,以及可能会有的对目录的描述
  2. 进入到最终目录后点击进入详情页的查看,详情页包括最终目录所属的前面所有层级/目录的标题内容,以及最终目录的详细内容
  3. 详细内容除2描述以外还需要展示类似评论的局部功能(可进行点赞和取消点赞操作),对详情页的标记功能,该目录是否有帮助功能,以及添加对这个详情页自己的想法的功能
  4. 详情页的每个操作尽量提示用户操作结果
  5. UI尚未作出要求

后端

  1. 多级表设计
  2. 尽量用最少的接口进行与服务器的交流

前端开发

多级目录的UI小框架

插一嘴 我的实现流程是在应用现有的activity的view上动态添加新的view,也就是每一级目录新增一个view
我在activity和view之间犹豫考量了一下, 最终认为actviity的形式有点小题大做,毕竟也只是显示一个view,上面显示一些基本的信息,顶多最终的详情页可能值一个activity,但是在新建5个activity和用一个view进行4个的复件加一个单独处理的详情页的view之间,我选择了后者,毕竟光是数据在不同activity之间的传输就已经够我的脑子宕机好几天了

回到正题,我用的是别的大佬写好的关于动态创建一个目录页面view的代码,然后进行魔改的方式,写了一个管理器来动态创建view
直接上源码

public class CustomViewMgr {



    //创建一个容器用于存放view,进行管理
//    List<View> views;
//    ViewGroup curView;
    protected LayoutInflater inflater;
    public CustomViewMgr(Context context) {
        //初始化

        inflater = (LayoutInflater) context.getSystemService(LAYOUT_INFLATER_SERVICE);
    }

    public LayoutInflater getInflater(){
        return this.inflater;
    }

    /**
     * 根据layout和对应的view找到需要新生成的view,为了方便拓展接收和返回都设置为了object
     *
     * @param oldView   原来在显示的view
     * @param layoutId  你新的xml的id
     * @param newViewId 你新的xml对应的viewId
     * @return Object
     */
    public Object getNewView(View oldView, int layoutId, int newViewId) {
        if (oldView != null) {
            oldView.setVisibility(View.GONE);
        }
        //获得需要新显示的layout
        ConstraintLayout constraintLayout2 = (ConstraintLayout) inflater.inflate(layoutId, null);
        //根据layout获得需要的view
        //添加到view容器中
        return constraintLayout2.findViewById(newViewId);
    }

    public void refreshRecycleView(RecyclerView recyclerView, NewsItemAdapter temAdapter,ViewGroup curView) {

        //这一步是把绑定好数据的适配器添加到视图上
        recyclerView.setAdapter(temAdapter);
        //这一步是清除要展示的view的父级,否则会闪退报错
        ViewGroup parent_tem = (ViewGroup) recyclerView.getParent();
        parent_tem.removeView(recyclerView);
        //最后再把视图和配套的数据添加到现有的view中
        curView.addView(recyclerView);
    }
}

这个CustomViewMgr类其实很简单,主要是用来找到位于其他xml的view,比如说我想在某个view上加入其他view里的某个组件(按钮,列表之类的),通过这个类的getNewView,第一个参数可以默认填null,我这里主要是图省事,希望在每创建新的view的时候可以自动隐藏之前的view就写在了这里面,主要是后面两个,第一个是layoutid,第二个是你需要新建的view的id,就可以返回你需要的view了,为什么这么麻烦,因为如果你不在对应的layout下找你的view,系统会默认在当前的view下找你的这个view,如果刚你你新建的view是在当前的view下,那就没事,但如果不在的话就会直接报错闪退,提示你当前的view是没有你要的view的
至于这个CustomViewMgr类的第二个refreshRecycleView方法主要是针对RecyclerView 这个view的,如果不在创建之前把他的父级目录移除然后新增到现在的view下的话,他会报错异常说你需要先移除RecyclerView 的父级目录才能新增,其他的view不知道有没有这个问题,以后遇到再说吧

前端xml

在res/anim下创建有关动画的xml

<?xml version="1.0" encoding="utf-8"?>
<layoutAnimation xmlns:android="http://schemas.android.com/apk/res/android"
    android:animation="@anim/slide_in_left"
    android:animationOrder="normal"
    android:delay="15%">

</layoutAnimation>

在res/drawable下创建分割水平组件的xml

<?xml version="1.0" encoding="utf-8"?>
<shape android:shape="rectangle"
    xmlns:android="http://schemas.android.com/apk/res/android" >
    <size android:height="1dp" android:width="100dp"/>
</shape>

在res/layout下创建详情页面的xml

<?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"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#ececed"
    tools:context=".TestActivity">

	//这个LineraLayout是详情页的view
    <LinearLayout
        android:id="@+id/showNewView"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:background="#fff"
        android:gravity="center_horizontal"
        android:orientation="vertical"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="@dimen/common_15dp"
            android:divider="@drawable/divider"
            android:gravity="center"
            android:orientation="horizontal"
            android:showDividers="middle">

            <LinearLayout
                android:id="@+id/solve_btn"
                android:gravity="center"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:orientation="vertical">

                <ImageView
                    android:layout_width="50sp"
                    android:layout_height="50sp"
                    android:src="@drawable/pic" />
                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="已解决"/>
            </LinearLayout>

            <LinearLayout
                android:id="@+id/mark_btn"
                android:gravity="center"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:orientation="vertical">

                <ImageView
                    android:layout_width="50sp"
                    android:layout_height="50sp"
                    android:src="@drawable/pic" />
                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="标记"/>
            </LinearLayout>
            <LinearLayout
                android:id="@+id/add_btn"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:gravity="center"
                android:orientation="vertical">

                <ImageView
                    android:layout_width="50sp"
                    android:layout_height="50sp"
                    android:src="@drawable/pic" />
                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:textSize="12sp"
                    android:text="我的想法"/>
            </LinearLayout>
        </LinearLayout>

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:orientation="vertical">

            <TextView
                android:id="@+id/menu1_text"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_margin="15dp"
                android:text="测试"
                android:textColor="#000"
                android:textSize="30dp" />

            <TextView
                android:id="@+id/menu2_text"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="测试"
                android:textColor="#000"
                android:textSize="20dp" />

            <TextView
                android:id="@+id/menu3_text"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_margin="15dp"
                android:text="测试"
                android:textColor="#000"
                android:textSize="20dp" />

            <TextView
                android:id="@+id/menu4_text"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="测试"
                android:textColor="#000"
                android:textSize="20dp" />
        </LinearLayout>

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:gravity="center_horizontal|center_vertical"
            android:orientation="vertical">

            <TextView
                android:id="@+id/new_view_text"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_margin="15dp"
                android:text="测试"
                android:textAlignment="center"
                android:textColor="#000"
                android:textSize="20dp"
                android:textStyle="bold" />
        </LinearLayout>


        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/showCommentView"

            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:layout_marginTop="20dp"
            android:orientation="vertical"
            app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager">

        </androidx.recyclerview.widget.RecyclerView>


    </LinearLayout>

	//------------这个RecyclerView就是显示每级目录的view
    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/menuRecycleView"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:clipToPadding="false"
        android:layoutAnimation="@anim/layout_slide_in_left"
        android:orientation="vertical"
        app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

    </androidx.recyclerview.widget.RecyclerView>
</androidx.constraintlayout.widget.ConstraintLayout>

如果你这里报异常说找不到RecyclerView组件的话
需要在对应的build.gradle下写入
implementation 'androidx.recyclerview:recyclerview:1.0.0'
然后sync(androidstudio右上角的海豚)一下
上面的这个xml既包括了详情页的view,也包括了显示每级目录的view,当然你可以再创建一个xml来单独存放每级目录的view,这里我就是lazy了而已…

在res/layout下创建关于每个目录中的item的xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_marginStart="10dp"
    android:layout_marginTop="10dp"
    app:cardCornerRadius="4dp"
    app:cardElevation="4dp">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:padding="10dp">

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal">

        <ImageView
            android:layout_width="20sp"
            android:layout_height="20sp"
            android:src="@mipmap/ic_launcher"
            />

            <TextView
                android:id="@+id/textTitle"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="test "
                android:paddingLeft="10sp"
                android:textColor="#212121"
                android:textSize="18sp"
                android:textStyle="bold" />


        </LinearLayout>


        <TextView
            android:id="@+id/textDescription"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:textColor="#757575"
            android:textIsSelectable="true"
            android:textSize="16sp"/>
        <TextView
            android:id="@+id/textZan"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:textColor="#757575"
            android:text=""
            android:textAlignment="textEnd"
            android:textSize="16sp"/>

    </LinearLayout>

</androidx.cardview.widget.CardView>

如果你这里提示没有CardView的,和上面的RecyclerView一样,在对应的build.grale加上下面这个
implementation 'androidx.cardview:cardview:1.0.0'
然后sync一下

前端代码—本地demo版

然后是才终于轮到activity
新建一个activity类,继承Activity
因为是demo阶段,所以没有涉及到服务器,下面的数据部分是手动添加的假数据

package com.yeyupiaoling.testvad;

import android.app.Activity;
import android.app.AlertDialog;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.recyclerview.widget.RecyclerView;
import com.yeyupiaoling.testvad.CustomView.CustomViewMgr;
import java.util.ArrayList;
import java.util.List;

public class TestActivity extends Activity {

    int menu1 = 0;
    int menu2 = 0;
    int menu3 = 0;
    int menu4 = 0;
    LayoutInflater inflater;
    ConstraintLayout parent;

    //创建一个容器用于存放view,进行管理
    List<View> views;
    ViewGroup curView;
    CustomViewMgr customViewMgr;

    //    编辑界面
    LinearLayout edit_view;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // 初始化
        views = new ArrayList<>();
        edit_view = null;
        setContentView(R.layout.activity_test);
        curView = findViewById(R.id.activity_main);

        customViewMgr = new CustomViewMgr(getApplicationContext());

        RecyclerView newRecyclerView = (RecyclerView) customViewMgr.getNewView(null, R.layout.activity_menu1, R.id.menuRecycleView);


        List<NewsItem> newsItems = new ArrayList<>();

        for (int i = 0; i < 15; i++) {
            newsItems.add(new NewsItem("一级目录" + i, "this is a news about pure doing a new function in android studio"));
        }
        NewsItemAdapter adapter = new NewsItemAdapter(newsItems);


        adapter.setOnItemClickListener(new NewsItemAdapter.OnItemClickListener() {
            @Override
            public void onItemClick(int postion, View view) {
                menu1 = postion;
                //这一步是找到需要展示的view
                RecyclerView recycleView_tem = (RecyclerView) customViewMgr.getNewView(newRecyclerView, R.layout.activity_menu1, R.id.menuRecycleView);
                List<NewsItem> newsItems = new ArrayList<>();
                for (int i = 0; i < 15; i++) {
                    newsItems.add(new NewsItem("二级目录" + i, "this is a news about pure doing a new function in android studio"));
                }
                NewsItemAdapter adapter_tem = new NewsItemAdapter(newsItems);

                adapter_tem.setOnItemClickListener(new NewsItemAdapter.OnItemClickListener() {
                    @Override
                    public void onItemClick(int postion, View view) {
                        menu2 = postion;
//                        parent.removeView(newRecyclerView1);
//                        ConstraintLayout constraintLayout3 = (ConstraintLayout)inflater.inflate(R.layout.activity_menu2,null);
//                        RecyclerView newRecyclerView1 = (RecyclerView) constraintLayout3.findViewById(R.id.menu2RecycleView);
                        RecyclerView recycleView_tem2 = (RecyclerView) customViewMgr.getNewView(recycleView_tem, R.layout.activity_menu1, R.id.menuRecycleView);
                        //这一步是建立数据
                        List<NewsItem> newsItems = new ArrayList<>();

                        for (int i = 0; i < 15; i++) {
                            newsItems.add(new NewsItem("三级目录" + i, "this is a news about pure doing a new function in android studio"));
                        }
                        //这一步是绑定数据
                        NewsItemAdapter adapter1 = new NewsItemAdapter(newsItems);
                        //这一步是绑定点击事件
                        adapter1.setOnItemClickListener(new NewsItemAdapter.OnItemClickListener() {
                            @Override
                            public void onItemClick(int postion, View view) {
                                menu3 = postion;
                                RecyclerView recyclerView_tem3 = (RecyclerView) customViewMgr.getNewView(recycleView_tem2, R.layout.activity_menu1, R.id.menuRecycleView);
                                List<NewsItem> newsItems = new ArrayList<>();

                                for (int i = 0; i < 15; i++) {
                                    newsItems.add(new NewsItem("终极目录" + i, "this is a news about pure doing a new function in android studio"));
                                }
                                //这一步是绑定数据
                                NewsItemAdapter adapter1 = new NewsItemAdapter(newsItems);
                                adapter1.setOnItemClickListener(new NewsItemAdapter.OnItemClickListener() {
                                    @Override
                                    public void onItemClick(int postion, View view) {
                                        menu4 = postion;
//                                        Button test = (Button) getNewView( recyclerView_tem3,R.layout.activity_menu1,R.id.showRecycleView);
//                                        refreshView(test);
                                        show_last_view();
                                    }
                                });
                                customViewMgr.refreshRecycleView(recyclerView_tem3, adapter1, curView);
                                views.add(recyclerView_tem3);
                            }
                        });
                        customViewMgr.refreshRecycleView(recycleView_tem2, adapter1, curView);
                        views.add(recycleView_tem2);
                    }
                });

                customViewMgr.refreshRecycleView(recycleView_tem, adapter_tem, curView);
                views.add(recycleView_tem);
            }
        });
        customViewMgr.refreshRecycleView(newRecyclerView, adapter, curView);
        views.add(newRecyclerView);
    }


    @Override
    public void onBackPressed() {
        if (views.size() > 0) {
            //说明还有上一级,隐藏当前返回上一级
            if (views.size() != 1) {
                views.get(views.size() - 2).setVisibility(View.VISIBLE);
                curView.removeView(views.get(views.size() - 1));
                views.remove(views.get(views.size() - 1));
            } else {
                views.get(0).setVisibility(View.GONE);
                views.remove(views.get(views.size() - 1));
            }

        } else {
            super.onBackPressed();
        }
    }

	//这个是显示详情页面的view
    private void show_last_view() {
        String result = "   这是学生顶撞老师的最常见原因。\n" +
                "   解决方法——教师开口之前,先询问一下,调查一下,就可以避免很多师生冲突。";

        views.get(views.size() - 1).setVisibility(View.GONE);
        View inflate = customViewMgr.getInflater().inflate(R.layout.activity_menu1, null);
        LinearLayout linearLayout = (LinearLayout) inflate.findViewById(R.id.showNewView);
        ViewGroup parent = (ViewGroup) linearLayout.getParent();
        parent.removeView(linearLayout);
        TextView textView1 = (TextView) linearLayout.findViewById(R.id.menu1_text);
        textView1.setText("纪律问题");
        TextView textView2 = (TextView) linearLayout.findViewById(R.id.menu2_text);
        textView2.setText("顶撞老师");
        TextView textView3 = (TextView) linearLayout.findViewById(R.id.menu3_text);
        textView3.setText("从教师责任的角度分析");
        TextView textView4 = (TextView) linearLayout.findViewById(R.id.menu4_text);
        textView4.setText("(1)老师冤枉了学生");
        TextView textView = (TextView) linearLayout.findViewById(R.id.new_view_text);
        textView.setText(result);
        RecyclerView recyclerView = (RecyclerView) linearLayout.findViewById(R.id.showCommentView);
        List<NewsItem> items = new ArrayList<>();
        items.add(new NewsItem("Mr.王", "我觉得这么做会更好一点", "30"));
        items.add(new NewsItem("Mr.张", "我觉得这么做会更好一点", "20"));
        items.add(new NewsItem("Mr.赵", "我觉得这么做会更好一点", "10"));
        items.add(new NewsItem("Mr.赵", "我觉得这么做会更好一点", "10"));
        items.add(new NewsItem("Mr.赵", "我觉得这么做会更好一点", "10"));
        items.add(new NewsItem("Mr.赵", "我觉得这么做会更好一点", "10"));
        items.add(new NewsItem("Mr.李", "我觉得这么做会更好一点", "0"));
        NewsItemAdapter adapter = new NewsItemAdapter(items);
        recyclerView.setAdapter(adapter);
        adapter.setOnItemClickListener(new NewsItemAdapter.OnItemClickListener() {
            @Override
            public void onItemClick(int postion, View view) {
                AlertDialog.Builder builder = new AlertDialog.Builder(TestActivity.this);
                builder.setTitle("确认");
                builder.setMessage("你进行了点赞");
                builder.show();
            }
        });
        LinearLayout solve_ly = linearLayout.findViewById(R.id.solve_btn);
        solve_ly.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                AlertDialog.Builder builder = new AlertDialog.Builder(TestActivity.this);
                builder.setTitle("确认");
                builder.setMessage("已标记为解决");
                builder.show();
                return false;
            }
        });
        LinearLayout mark_ly = linearLayout.findViewById(R.id.mark_btn);
        mark_ly.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                AlertDialog.Builder builder = new AlertDialog.Builder(TestActivity.this);
                builder.setTitle("确认");
                builder.setMessage("已标记");
                builder.show();
                return false;
            }
        });
        LinearLayout add_ly = linearLayout.findViewById(R.id.add_btn);
        add_ly.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                //进入编辑的view
                views.get(views.size() - 1).setVisibility(View.GONE);
                if (views.contains(edit_view)) {
                    int index = views.indexOf(views.contains(edit_view));
                    views.get(index).setVisibility(View.VISIBLE);
                    return false;
                }
                View inflate = customViewMgr.getInflater().inflate(R.layout.add_opinion, null);
                LinearLayout linearLayout = (LinearLayout) inflate.findViewById(R.id.add_view);
                ViewGroup parent1 = (ViewGroup) linearLayout.getParent();
                parent1.removeView(linearLayout);
                Button back_add_view = (Button) linearLayout.findViewById(R.id.back_add_view);
                EditText editText = (EditText) linearLayout.findViewById(R.id.add_opinion_text);
                editText.setHint(menu1 + "\n" + menu2 + "\n" + menu3 + "\n" + menu4 + "\n" + "请输入您的想法");
                back_add_view.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        onBackPressed();
                    }
                });
                Button upload_opinion = (Button) linearLayout.findViewById(R.id.upload_new_opinion);
                upload_opinion.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        onBackPressed();
                        AlertDialog.Builder builder = new AlertDialog.Builder(TestActivity.this);
                        builder.setTitle("确认");
                        builder.setMessage("上传完成");
                        builder.show();
                    }
                });
                curView.addView(linearLayout);
                edit_view = linearLayout;
                views.add(linearLayout);
                return false;
            }
        });
        curView.addView(linearLayout);
        views.add(linearLayout);

    }
}

如果以上的都能运行成功说明demo阶段就没问题了

前端代码—服务器版

下面是和服务器有关的前端代码展示
这里说一下, 因为我们接入了腾讯的即时通信,而这个需求是需要在这里面搭建的,因此如果你看不太懂的话也很正常
我专门创建了一个继承了Dialog的CustomView类,用来管理自定义的新建的view

逻辑说明

服务器相关的代码主要是在每一级的目录创建时需要先从服务器下拉数据,然后根据数据进行实时的view渲染和显示,涉及到一个延迟的问题,因为是自定义的所以没有写有关加载过程添加提示加载中的功能,这里只是做了一个简单的回调接口,在等待服务器响应后再执行view的生成
因为是继承了Dialog,所以存在点击view之外的界面所有的view都会消失的问题,因此需要设置setcancelable为false,然后重写一下onBackPressed这个方法
有关请求服务器的部分因为是外包搭建的框架,是用的library_commom 模块下的SubscribeUtils进行的请求,具体没有深究原理,不是重点
请求服务器的方式萝卜青菜各有所爱
有关详情页的部分有一些我是请求了服务器之后没有重新进入,而是在本地临时存了一些数据用来记录,然后实时更新,减少一点和服务器的请求以及增加一点体验感

package com.tencent.qcloud.tim.demo.helper;

import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;

import androidx.recyclerview.widget.RecyclerView;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.jbb.library_common.comfig.KeyContacts;
import com.jbb.library_common.retrofit.RetrofitManager;
import com.jbb.library_common.retrofit.other.BaseBean;
import com.jbb.library_common.retrofit.other.NetListeren;
import com.jbb.library_common.retrofit.other.SubscribeUtils;
import com.jbb.library_common.utils.ToastUtil;
import com.tencent.qcloud.tim.demo.R;
import com.tencent.qcloud.tim.demo.helper.custommsg.CustomMsgChooseListeren;
import com.tencent.qcloud.tim.demo.helper.custommsg.CustomMsgDialog;
import com.tencent.qcloud.tim.demo.helper.teacherquestion.CustomViewMgr;
import com.tencent.qcloud.tim.demo.helper.teacherquestion.NewsItem;
import com.tencent.qcloud.tim.demo.helper.teacherquestion.NewsItemAdapter;
import com.tencent.qcloud.tim.demo.helper.teacherquestion.TeacherPsyMethonResBean;
import com.tencent.qcloud.tim.demo.helper.teacherquestion.TeacherQuestionResBean;
import com.tencent.qcloud.tim.demo.utils.Constants;
import com.tencent.qcloud.tim.uikit.modules.chat.ChatLayout;
import com.tencent.qcloud.tim.uikit.modules.chat.layout.input.InputLayout;
import com.tencent.qcloud.tim.uikit.service.IMApiService;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Objects;

import static com.tencent.liteav.base.ContextUtils.getApplicationContext;

public class CustomVIew extends Dialog {

    private Context curContext;
    private ChatLayout curLayout;
    private InputLayout curInputLayout;

    private CustomViewMgr customViewMgr;

    private List<NewsItem> curMenuInfo;
    private View curView;
    private int curIndex;
    private int curMenu;
    private List<List<NewsItem>> menuInfos;
    private List<View> views;

    private HashMap<Integer, NewsItem> psyDetailInfo;
    private Button toMenu1, toMenu2;

    public CustomVIew(Context context, ChatLayout layout, InputLayout inputLayout) {
        super(context);
        this.curContext = context;
        this.curLayout = layout;
        this.curInputLayout = inputLayout;
        this.curMenuInfo = new LinkedList<>();
        this.curIndex = 0;
        this.curMenu = 0;
        this.views = new LinkedList<>();
        this.menuInfos = new LinkedList<>();
        this.psyDetailInfo = new HashMap();
        customViewMgr = new CustomViewMgr(context);
        init();
    }

    private void init() {
        //先弹出两个选择框,用户选择,第一个进入语料库,第二个进入新的问题心理合集功能
        LayoutInflater inflater = LayoutInflater.from(curContext);
        curView = inflater.inflate(R.layout.pure_diy_view, (ViewGroup) getWindow().getDecorView(), false);

        LinearLayout btns = curView.findViewById(R.id.pure_show_zhixingyuku_btn);

        toMenu1 = (Button) btns.findViewById(R.id.to_teacher_zhixingyuku);
        toMenu2 = (Button) btns.findViewById(R.id.to_teacher_psyquestion);

        toMenu1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                final CustomMsgDialog dialog = new CustomMsgDialog(curContext, curInputLayout);
                dialog.setListeren(new CustomMsgChooseListeren() {
                    @Override
                    public void messageChoose(String text) {
                        curLayout.getInputLayout().setTextInput(text);
                        dialog.dismiss();
                    }
                });
                dialog.showDialog();
            }
        });

        toMenu2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //这里要隐藏两个按钮的减轻事件
                toMenu1.setVisibility(View.GONE);
                toMenu2.setVisibility(View.GONE);
                setCancelable(false);
                add_menu(1, 0, new Callback() {
                    @Override
                    public void onSuccess() {
                        curMenu = 1;
                        //添加监听事件
                        add_menu(2, curMenuInfo.get(curIndex).getId(), new Callback() {
                            @Override
                            public void onSuccess() {
                                curMenu = 2;
                                add_menu(3, curMenuInfo.get(curIndex).getId(), new Callback() {
                                    @Override
                                    public void onSuccess() {
                                        curMenu = 3;
                                        add_menu(4, curMenuInfo.get(curIndex).getId(), new Callback() {
                                            @Override
                                            public void onSuccess() {
                                                curMenu = 4;
                                                //进入详情页面
                                                show_last_view();
                                            }

                                            @Override
                                            public void onFail() {

                                            }
                                        });
                                    }

                                    @Override
                                    public void onFail() {

                                    }
                                });
                            }

                            @Override
                            public void onFail() {

                            }
                        });
                    }

                    @Override
                    public void onFail() {

                    }
                });
            }
        });

        setContentView(curView);
        setCancelable(true);
        Window dialogWindow = getWindow();
        dialogWindow.setGravity(Gravity.CENTER);
        dialogWindow.setWindowAnimations(R.style.bottomdialogAnim);
        dialogWindow.setBackgroundDrawableResource(R.color.common_transparent);
        WindowManager.LayoutParams lp = dialogWindow.getAttributes();


        lp.width = ViewGroup.LayoutParams.MATCH_PARENT; //
        lp.height = ViewGroup.LayoutParams.WRAP_CONTENT;
        dialogWindow.setAttributes(lp);

    }

    private void getMenuInfo(int menu, int pid, final Callback callback) {
        List<NewsItem> result = new ArrayList<>();
        SubscribeUtils.subscribe(RetrofitManager.getInstance().getService(IMApiService.class)
                .loadTeacherQuestionList(KeyContacts.token, menu, pid), TeacherQuestionResBean.class, new NetListeren<TeacherQuestionResBean>() {
            @Override
            public void onSuccess(TeacherQuestionResBean teacherQuestionResBean) {
                if (teacherQuestionResBean.getData().size() <= 0) {
                    ToastUtil.showCustomToast("加载出现异常,请重启");
                    return;
                }
                curMenuInfo = teacherQuestionResBean.getData();
                menuInfos.add(curMenuInfo);
                callback.onSuccess();
            }

            @Override
            public void onError(Exception e) {
                callback.onFail();
            }
        });

    }

    public interface Callback {
        void onSuccess();

        void onFail();
    }

    private void add_menu(final int menu, final int pid, final Callback callback) {

        getMenuInfo(menu, pid, new Callback() {
            @Override
            public void onSuccess() {
//                setCancelable(false);
                View oldView = null;
                if (views.size() != 0) {
                    //说明有遗留的view,需要隐藏
                    oldView = views.get(views.size() - 1);
                }
                final RecyclerView newRecyclerView = (RecyclerView) customViewMgr.getNewView(oldView, R.layout.activity_menu1, R.id.menuRecycleView);
                NewsItemAdapter adapter = new NewsItemAdapter(curMenuInfo);

                adapter.setOnItemClickListener(new NewsItemAdapter.OnItemClickListener() {
                    @Override
                    public void onItemClick(int postion, View view) {
                        curIndex = postion;
                        System.out.println(curMenuInfo.get(postion));
                        psyDetailInfo.put(menu, curMenuInfo.get(postion));
                        callback.onSuccess();
                    }
                });
                customViewMgr.refreshRecycleView(newRecyclerView, adapter, (ViewGroup) curView);
                views.add(newRecyclerView);
            }

            @Override
            public void onFail() {
                ToastUtil.showCustomToast("加载失败~");
//                setCancelable(true);
            }
        });
    }

    private int final_menu = 4;

    @Override
    public void onBackPressed() {

        if (views.size() > 0) {
            //说明还有上一级,隐藏当前返回上一级
            if (views.size() != 1) {
                views.get(views.size() - 2).setVisibility(View.VISIBLE);
                ViewGroup tem = (ViewGroup) curView;
                tem.removeView(views.get(views.size() - 1));
                views.remove(views.get(views.size() - 1));

                curMenu--;
                if (curMenu < final_menu) {
                    menuInfos.remove(menuInfos.size() - 1);
                    curMenuInfo = menuInfos.get(menuInfos.size() - 1);
                }
            } else {
                views.get(0).setVisibility(View.GONE);
                views.remove(views.get(views.size() - 1));

                toMenu1.setVisibility(View.VISIBLE);
                toMenu2.setVisibility(View.VISIBLE);
                setCancelable(true);
            }

        } else {
            super.onBackPressed();
        }
    }

    private void show_last_view() {

        curMenu = 5;
        List<NewsItem> items = new ArrayList<>();
//        items.add(new NewsItem("Mr.王", "我觉得这么做会更好一点", "30"));

        SubscribeUtils.subscribe(RetrofitManager.getInstance().getService(IMApiService.class)
                        .getTeacherPsyMethodInfo(KeyContacts.token, psyDetailInfo.get(4).getId(),Constants.CUR_CHAT_ID), TeacherPsyMethonResBean.class
                , new NetListeren<TeacherPsyMethonResBean>() {
                    @Override
                    public void onSuccess(TeacherPsyMethonResBean teacherPsyMethonResBean) {
                        //这是解决方法
                        final JSONArray comments = (JSONArray) teacherPsyMethonResBean.getData().get("methods");
                        final List<NewsItem> comment = JSONObject.parseArray(comments.toJSONString(), NewsItem.class);
                        //这是解决方法对应用户是否点赞
                        final JSONArray isZans = (JSONArray) teacherPsyMethonResBean.getData().get("isZan");
                        final List<HashMap> isZan = JSONObject.parseArray(isZans.toJSONString(), HashMap.class);
                        //这是查看当前目录用户是否进行了标记
                        int status = Integer.parseInt(teacherPsyMethonResBean.getData().get("status").toString());
                        //这是查看当前目录用户是否觉得有效
                        int is_effect = Integer.parseInt(teacherPsyMethonResBean.getData().get("is_effect").toString());
                        final int[] tem_info = new int[]{status,is_effect};
                        if (comment.size() <= 0) {
                            ToastUtil.showCustomToast("期待您的填写");
                        }
                        if (isZan.size() != 0) {
                            for (int i = 0; i < comment.size(); i++) {
                                for (int j = 0; j < isZan.size(); j++) {
                                    if (isZan.get(j).get("zid").equals(comment.get(i).getId() + "")) {
                                        comment.get(i).setZan(true);
                                    }
                                }
                            }
                        }
                        String result = Objects.requireNonNull(psyDetailInfo.get(4)).getContent();
                        views.get(views.size() - 1).setVisibility(View.GONE);
                        View inflate = customViewMgr.getInflater().inflate(R.layout.activity_menu1, (ViewGroup) getWindow().getDecorView(), false);
                        LinearLayout linearLayout = (LinearLayout) inflate.findViewById(R.id.showNewView);
                        ViewGroup parent = (ViewGroup) linearLayout.getParent();
                        parent.removeView(linearLayout);
                        TextView textView1 = (TextView) linearLayout.findViewById(R.id.menu1_text);
                        textView1.setText(Objects.requireNonNull(psyDetailInfo.get(1)).getTitle());
                        TextView textView2 = (TextView) linearLayout.findViewById(R.id.menu2_text);
                        textView2.setText(Objects.requireNonNull(psyDetailInfo.get(2)).getTitle());
                        TextView textView3 = (TextView) linearLayout.findViewById(R.id.menu3_text);
                        textView3.setText(Objects.requireNonNull(psyDetailInfo.get(3)).getTitle());
                        TextView textView4 = (TextView) linearLayout.findViewById(R.id.menu4_text);
                        textView4.setText(Objects.requireNonNull(psyDetailInfo.get(4)).getTitle());
                        TextView textView = (TextView) linearLayout.findViewById(R.id.new_view_text);
                        textView.setText(result);
                        final RecyclerView recyclerView = (RecyclerView) linearLayout.findViewById(R.id.showCommentView);
                        final NewsItemAdapter adapter = new NewsItemAdapter(comment);
                        recyclerView.setAdapter(adapter);
                        adapter.setOnItemClickListener(new NewsItemAdapter.OnItemClickListener() {
                            @Override
                            public void onItemClick(final int postion, final View view) {
                                if (comment.get(postion).isZan()) {
                                    final AlertDialog.Builder builder = new AlertDialog.Builder(curContext);
//                        builder.setTitle("确认");
                                    builder.setMessage("是否取消点赞");
                                    builder.setPositiveButton("是的", new OnClickListener() {
                                        @Override
                                        public void onClick(final DialogInterface dialog, int which) {
                                            int zanId = comment.get(postion).getId();
                                            SubscribeUtils.subscribe(RetrofitManager.getInstance().getService(IMApiService.class).psyNoDizan(KeyContacts.token, zanId),
                                                    BaseBean.class, new NetListeren<BaseBean>() {
                                                        @Override
                                                        public void onSuccess(BaseBean baseBean) {
                                                            ToastUtil.showCustomToast("取消成功");
                                                            dialog.dismiss();
                                                            comment.get(postion).setZan(false);
                                                            comment.get(postion).setDizan(comment.get(postion).getDizan() - 1);
                                                            recyclerView.setAdapter(adapter);
                                                        }
                                                    });
                                        }
                                    });
                                    builder.show();
                                } else {
                                    AlertDialog.Builder builder = new AlertDialog.Builder(curContext);
//                        builder.setTitle("确认");
                                    builder.setMessage("是否进行点赞");
                                    builder.setPositiveButton("是的", new OnClickListener() {
                                        @Override
                                        public void onClick(final DialogInterface dialog, int which) {
                                            int zanId = comment.get(postion).getId();
                                            SubscribeUtils.subscribe(RetrofitManager.getInstance().getService(IMApiService.class).psyDizan(KeyContacts.token, zanId),
                                                    BaseBean.class, new NetListeren<BaseBean>() {
                                                        @Override
                                                        public void onSuccess(BaseBean baseBean) {
                                                            ToastUtil.showCustomToast("点赞成功");
                                                            dialog.dismiss();
                                                            comment.get(postion).setZan(true);
                                                            comment.get(postion).setDizan(comment.get(postion).getDizan() + 1);
                                                            recyclerView.setAdapter(adapter);
                                                        }
                                                    });
                                        }
                                    });
                                    builder.show();
                                }
                            }
                        });
                        LinearLayout solve_ly = linearLayout.findViewById(R.id.solve_btn);
                        solve_ly.setOnTouchListener(new View.OnTouchListener() {
                            @Override
                            public boolean onTouch(View v, MotionEvent event) {
                                if(tem_info[1]==0){
                                    //说明该问题用户没有标记为已解决
                                    AlertDialog.Builder builder = new AlertDialog.Builder(curContext);
                                    builder.setMessage("该问题的解决思路以及方法是否有效?");
                                    builder.setPositiveButton("是", new OnClickListener() {
                                        @Override
                                        public void onClick(final DialogInterface dialog, int which) {
                                            SubscribeUtils.subscribe(RetrofitManager.getInstance().getService(IMApiService.class).updatePosTeacherPsyMethodInfo(KeyContacts.token,
                                                    psyDetailInfo.get(4).getId(), tem_info[0], 1, Constants.CUR_CHAT_ID), BaseBean.class, new NetListeren<BaseBean>() {
                                                @Override
                                                public void onSuccess(BaseBean baseBean) {
                                                    tem_info[1] = 1;
                                                    ToastUtil.showCustomToast("感谢您的反馈");
                                                    dialog.dismiss();
                                                }
                                            });
                                        }
                                    });
                                    builder.setNegativeButton("取消", new OnClickListener() {
                                        @Override
                                        public void onClick(DialogInterface dialog, int which) {
                                            dialog.dismiss();
                                        }
                                    });
                                    builder.show();
                                }
                                else if(tem_info[1]==1){
                                    //说明该问题用户为已解决
                                    AlertDialog.Builder builder = new AlertDialog.Builder(curContext);
                                    builder.setMessage("是否取消有效?");
                                    builder.setPositiveButton("是", new OnClickListener() {
                                        @Override
                                        public void onClick(final DialogInterface dialog, int which) {
                                            SubscribeUtils.subscribe(RetrofitManager.getInstance().getService(IMApiService.class).updatePosTeacherPsyMethodInfo(KeyContacts.token,
                                                    psyDetailInfo.get(4).getId(), tem_info[0], 0, Constants.CUR_CHAT_ID), BaseBean.class, new NetListeren<BaseBean>() {
                                                @Override
                                                public void onSuccess(BaseBean baseBean) {
                                                    tem_info[1] = 0;
                                                    ToastUtil.showCustomToast("感谢您的反馈");
                                                    dialog.dismiss();
                                                }
                                            });
                                        }
                                    });
                                    builder.setNegativeButton("取消", new OnClickListener() {
                                        @Override
                                        public void onClick(DialogInterface dialog, int which) {
                                            dialog.dismiss();
                                        }
                                    });
                                    builder.show();
                                }
                                return false;
                            }
                        });
                        LinearLayout mark_ly = linearLayout.findViewById(R.id.mark_btn);
                        mark_ly.setOnTouchListener(new View.OnTouchListener() {
                            @Override
                            public boolean onTouch(View v, MotionEvent event) {
                                if(tem_info[0]==0){
                                    //说明该问题用户没有标记
                                    AlertDialog.Builder builder = new AlertDialog.Builder(curContext);
                                    builder.setMessage("是否标记该学生为此问题典型?");
                                    builder.setPositiveButton("是", new OnClickListener() {
                                        @Override
                                        public void onClick(final DialogInterface dialog, int which) {
                                            SubscribeUtils.subscribe(RetrofitManager.getInstance().getService(IMApiService.class).updatePosTeacherPsyMethodInfo(KeyContacts.token,
                                                    psyDetailInfo.get(4).getId(), 1, tem_info[1], Constants.CUR_CHAT_ID), BaseBean.class, new NetListeren<BaseBean>() {
                                                @Override
                                                public void onSuccess(BaseBean baseBean) {
                                                    tem_info[0] = 1;
                                                    ToastUtil.showCustomToast("感谢您的反馈");
                                                    dialog.dismiss();
                                                }
                                            });
                                        }
                                    });
                                    builder.setNegativeButton("否", new OnClickListener() {
                                        @Override
                                        public void onClick(DialogInterface dialog, int which) {
                                            dialog.dismiss();
                                        }
                                    });
                                    builder.show();
                                }else if(tem_info[0]==1){
                                    //说明该问题用户有标记
                                    AlertDialog.Builder builder = new AlertDialog.Builder(curContext);
                                    builder.setMessage("是否取消标记该学生为此问题典型?");
                                    builder.setPositiveButton("是", new OnClickListener() {
                                        @Override
                                        public void onClick(final DialogInterface dialog, int which) {
                                            SubscribeUtils.subscribe(RetrofitManager.getInstance().getService(IMApiService.class).updatePosTeacherPsyMethodInfo(KeyContacts.token,
                                                    psyDetailInfo.get(4).getId(), 0, tem_info[1], Constants.CUR_CHAT_ID), BaseBean.class, new NetListeren<BaseBean>() {
                                                @Override
                                                public void onSuccess(BaseBean baseBean) {
                                                    tem_info[0] = 0;
                                                    ToastUtil.showCustomToast("感谢您的反馈");
                                                    dialog.dismiss();
                                                }
                                            });
                                        }
                                    });
                                    builder.setNegativeButton("否", new OnClickListener() {
                                        @Override
                                        public void onClick(DialogInterface dialog, int which) {
                                            dialog.dismiss();
                                        }
                                    });
                                    builder.show();
                                }
                                return false;
                            }
                        });
                        LinearLayout add_ly = linearLayout.findViewById(R.id.add_btn);

                        final ViewGroup tem = (ViewGroup) curView;
                        add_ly.setOnTouchListener(new View.OnTouchListener() {
                            @Override
                            public boolean onTouch(View v, MotionEvent event) {
                                //进入编辑的view
                                curMenu = 6;
                                views.get(views.size() - 1).setVisibility(View.GONE);
//                if (views.contains(edit_view)) {
//                    int index = views.indexOf(views.contains(edit_view));
//                    views.get(index).setVisibility(View.VISIBLE);
//                    return false;
//                }
                                View inflate = customViewMgr.getInflater().inflate(R.layout.add_opinion, tem, false);
                                LinearLayout linearLayout = (LinearLayout) inflate.findViewById(R.id.add_view);
                                ViewGroup parent1 = (ViewGroup) linearLayout.getParent();
                                parent1.removeView(linearLayout);
                                Button back_add_view = (Button) linearLayout.findViewById(R.id.back_add_view);
                                TextView hintText = (TextView) linearLayout.findViewById(R.id.opinion_hint);
                                final EditText editText = (EditText) linearLayout.findViewById(R.id.add_opinion_text);
                                hintText.setText(Objects.requireNonNull(psyDetailInfo.get(1)).getTitle()
                                        + "\n" + Objects.requireNonNull(psyDetailInfo.get(2)).getTitle()
                                        + "\n" + Objects.requireNonNull(psyDetailInfo.get(3)).getTitle()
                                        + "\n" + Objects.requireNonNull(psyDetailInfo.get(4)).getTitle());
                                back_add_view.setOnClickListener(new View.OnClickListener() {
                                    @Override
                                    public void onClick(View v) {
                                        onBackPressed();
                                    }
                                });
                                Button upload_opinion = (Button) linearLayout.findViewById(R.id.upload_new_opinion);
                                upload_opinion.setOnClickListener(new View.OnClickListener() {
                                    @Override
                                    public void onClick(View v) {

                                        AlertDialog.Builder builder = new AlertDialog.Builder(curContext);
                                        builder.setTitle("是否上传");
                                        builder.setPositiveButton("确认", new OnClickListener() {
                                            @Override
                                            public void onClick(final DialogInterface dialog, int which) {
                                                SubscribeUtils.subscribe(RetrofitManager.getInstance().getService(IMApiService.class).uploadTeacherOpinion(KeyContacts.token,
                                                        psyDetailInfo.get(4).getId(), editText.getText().toString()), BaseBean.class, new NetListeren<BaseBean>() {
                                                    @Override
                                                    public void onSuccess(BaseBean baseBean) {
                                                        ToastUtil.showCustomToast("上传成功,请返回上一级再次进入");
                                                        dialog.dismiss();
                                                        onBackPressed();
                                                    }
                                                });
                                            }
                                        });
                                        builder.setNegativeButton("取消", new OnClickListener() {
                                            @Override
                                            public void onClick(DialogInterface dialog, int which) {
                                                dialog.dismiss();
                                            }
                                        });
                                        builder.show();
                                    }
                                });
                                tem.addView(linearLayout);
                                views.add(linearLayout);

//                setContentView(linearLayout);
                                return false;
                            }
                        });
                        tem.addView(linearLayout);
                        views.add(linearLayout);
                    }
                });


    }
}

后端开发

表设计

用了一个DbSchema的工具,进行了表设计
子目录绑定父目录的id作为关联key
写之前觉得挺麻烦的, 实际做感觉也没那么复杂
DbSchema这个工具有几个挺好用的功能,第一个是可以在这个设计好的表里面随机生成假数据,另一个是可以像msyql一样导出sql文件,这样就可以直接导入mysql了
在这里插入图片描述

书写接口

目前项目中创建了5个接口来实现
一个是查询各级目录信息的接口,通过请求的目录层级和上一级的pid进行查询
一个是查询详情页的信息的接口,包括详情页所属的前面所有父级目录的信息,以及评论区的信息,以及该详情页是否被用户进行过标记,并且上传过自己的想法的信息
一个是进行点赞的接口
一个是进行取消点赞的接口
还有一个是更新详情页状态的接口

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/517747.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Win10笔记本无法正常启动代码0xc0000001解决方法

Win10笔记本无法正常启动代码0xc0000001解决方法。最近不少的用户在笔记本电脑安装Win10系统使用时&#xff0c;出现了蓝屏的情况&#xff0c;电脑显示错误代码0xc0000001无法启动到桌面使用。那么这个情况怎么去进行问题的解决呢&#xff1f;来看看以下的解决方法吧。 准备工作…

OpenCL编程指南-4.1OpenCL C编程

使用OpenCL C编写数据并行内核 OpenCL中的数据并行性表述为一个N维计算域&#xff0c;其中N1、2或3。N-D域定义了可以并行执行的工作项的总数。下面通过一个简单的例子来了解如何用OpenCL C编写一个数据并行内核&#xff0c;将两个浮点数数组相加。这个代码的串行版本求和时需…

在windows上通过QEMU快速上手RT-thread smart

参考链接 官方文档 资料下载 env-windows-v1.3.5.7z userapps 注意事项 通过QEMU仿真不同的平台&#xff0c;使用到的交叉编译工具也不一样&#xff0c;需要将相应工具的路径添加到系统PATH里&#xff1b;或者通过CMD定位到userapps&#xff0c;运行smart-env.bat xxx&…

【jvm系列-11】jvm性能调优篇---命令行工具的基本使用

JVM系列整体栏目 内容链接地址【一】初识虚拟机与java虚拟机https://blog.csdn.net/zhenghuishengq/article/details/129544460【二】jvm的类加载子系统以及jclasslib的基本使用https://blog.csdn.net/zhenghuishengq/article/details/129610963【三】运行时私有区域之虚拟机栈…

智能优化算法——下山单纯型算法

作者&#xff1a;非妃是公主 专栏&#xff1a;《智能优化算法》 博客地址&#xff1a;https://blog.csdn.net/myf_666 个性签&#xff1a;顺境不惰&#xff0c;逆境不馁&#xff0c;以心制境&#xff0c;万事可成。——曾国藩 文章目录 专栏推荐序一、算法流程1. 反射2. 膨胀…

马哈鱼SQLFLow数据流生成介绍

马哈鱼数据血缘分析器是当前最流行的数据血缘关系(data lineage)管理工具之一&#xff0c;它是一种通过分析SQL脚本来自动发现数据流向的工具。它通过生成一个简洁的图表来显示数据仓库中表/视图和列之间的数据流。支持超过20种流行的数据库&#xff0c;包括 bigquery, couchba…

项目风险的4种应对策略及实施条件

面对威胁或可能给项目带来消极影响的风险&#xff0c;我们一般采用规避、转移、缓解和接受的应对策略。 一、风险规避 风险规避策略是指项目团队采取行动来消除威胁&#xff0c;或保护项目免受风险影响的应对策略&#xff0c;通常包括改变项目管理计划&#xff0c;以完全消除威…

super_数学知识(质数筛选和约数学习)lesson08易错题记录

文章目录 回文质数第n小的质数素数个数 回文质数 先上代码 #include<iostream> #include<vector>//创建动态数组需要的头文件 #include<cstring>//使用memset需要的头文件 using namespace std; vector<int> q; bool arr[10000005]; //埃氏筛法找出所…

详解软件开发的标准过程(生命周期):跟着标准搞,设计没烦恼

目录 一.软件开发的生命周期总括 二.项目架构分类 C/S架构 B/S架构 三.详解软件需求 需求分类 需求获取 需求分析 四.详解面向对象分析&#xff08;OOA&#xff09; 概念理解&#xff1a; 统⼀建模语⾔UML UML的重要组成部分&#xff1a; ⽤例图的元素 识别参与者…

怎么搭建个人小型渲染农场?搭建渲染农场配置

渲染农场是众多机器组成的渲染集群&#xff0c;通常用来渲染你的单帧效果图或动画项目&#xff0c;我们借助渲染农场的力量&#xff0c;可以满足3D项目交期时间迫在眉睫的需求&#xff0c;当你试着在自己的机器上渲染一个复杂的动画项目时&#xff0c;可能需要几十小时的等待时…

gdb与symbol符号表文件的调试

目录 1&#xff0c;剥离命令 2&#xff0c;gdbdebug 文件的调试 今天在调试程序的时候发现&#xff0c;在测试部测试的程序都是剥离了符号表的&#xff0c;导致用gdb无法调试&#xff0c;只有找到符号表文件才能继续gdb调试&#xff0c;好在符号表文件是和程序一起发布的。之…

浅谈作为程序员如何写好文档:了解读者

我作为从一名懵懂的实习生转变为工程师的工作经历中&#xff0c;伴随着技术经验的成长&#xff0c;也逐渐意识到了编写文档是知识和经验传递给其他人的最有效方式。通过文档&#xff0c;可以分享我的技术知识和最佳实践&#xff0c;使其他人更好地理解我的工作。在这里&#xf…

Postgres : 创建schema、创建表空间与指定用户权限

1. 创建新的Schema 要创建 PostgreSQL 中的一个新的 schema&#xff0c;并创建一个只有该 schema 权限的新用户&#xff0c;请按照以下步骤操作&#xff1a; &#xff08;1&#xff09;打开 PostgreSQL 客户端并连接到数据库服务器。 &#xff08;2&#xff09;创建一个新的…

如何在Oracle存储过程发生异常时获取out类型参数的值

Oracle存储过程关于在出现&#xff08;自定义/自带&#xff09;异常下out类型参数的获取问题的分析 ✈️ 场景: 有一些关于金额和时间的精确且量大的计算需要在存储过程中完成。存储过程中有一些自定义的异常。并且将在RAISE前通过out类型的参数将详细的异常原因返回。 但是在…

商业智能BI分析报表很慢是什么原因?应该如何优化?

当下&#xff0c;数据计算已成为了分析工作中必不可少的高频次操作之一&#xff0c;而且在大数据的发展背景下&#xff0c;应用性能往往关系着项目的成败&#xff0c;成为了大家最为关注的产品技术参数。那么我们先来分析一下BI分析表计算很慢的原因是什么&#xff0c;再对症下…

Microsoft Dynamics 365 Business Central 生产订单扣料的几种方法

学习目标&#xff1a; 掌握生产订单扣料的几种方法 学习内容&#xff1a; Forward flush by routing operation&#xff08;通过工序&#xff1a;向前扣料&#xff09;Backward flush by routing operation&#xff08;通过工序&#xff1a;向后扣料&#xff09;Forward flus…

Java-Redis持久化之RDB操作

Java-Redis持久化之RDB操作 1.为什么redis需要持久化&#xff1f;2.什么是RDB操作?3.请你用自己的话讲下RDB的过程?4.如何恢复rdb文件? 1.为什么redis需要持久化&#xff1f; Redis是内存数据库&#xff0c;如果不将内存数据库保存到磁盘&#xff0c;那么服务器进程退出&am…

匿名对象的特性和使用场景你知道吗?

目录 一、匿名对象的概念 二、单参数和多参数构造场景的匿名对象 ①只有一个参数的构造函数 ②多个参数的构造函数 三、使用匿名对象作为函数的参数的缺省值 四、只为调用类中的一个函数时 五、匿名对象的特性 1、匿名对象的生命周期只有一行 2、匿名对象具有常性 3、当匿…

今天去面一个点工,HR要我会数据库,Linux还有Python,这合理吗?

软件测试出路在哪&#xff1f; 业务编程&#xff01;&#xff01; 1、软件测试的变化趋势 变化趋势1&#xff1a; 功能测试是核心&#xff0c;但是价值降低 目前测试这个行业&#xff0c;还是有大量的点工。但是行业的进步&#xff0c;技术的创新&#xff0c;导致了企业的需求…

不用下载的网页版Axure在这里

作为一名产品经理&#xff0c;你一定需要一款能够帮助你更好更快地制作原型&#xff0c;更方便地和团队协作的软件。网页版Axure工具替代即时设计无需下载激活&#xff0c;就可免费使用。那么&#xff0c;Axure网页版工具替代即时设计是如何进行的呢&#xff1f; 首先&#xf…