Android学习笔记——基础介绍_xhpi-程序员宅基地

技术标签: Android学习笔记  android  

目录

​​​​一、Android 的四大组件

二、UI的基石——Activity

1.创建Activity

2.跳转与关闭

3.Activity生命周期

4.Intent相关

 三、基础UI组件

1.View和ViewGroup

2.view的继承关系

 3.屏幕适配

3.1 基本概念

3.2 相对布局

3.3 点九图——Nine Patch图

四、事件传递

 五、高级UI组件

1.ListView

1.1 简介

 1.2 ListView复用机制

1.3 代码示例

2 RecyclerView

2.1 RecyclerView简介

 2.2 RecyclerView代码例子

③编写Activity

 2.3 Adapter:

2.4 复用(三级缓存 + 自定义缓存):

3 ListView和RecyclerView对比


​​​​一、Android 的四大组件

  • Activity: 包含用户界面的组件, 主要用于与用户交互
  • Service: 后台运行的解决方案,不需要用户交互的长期运行任务
  • BroadcastReceiver: 系统级的发布-订阅机制
  • ContentProvider: 不同应用程序之间共享数据
    Intent: 各组件之间进行交互、传递意图(动作和数据), 用户的一切行为可以由多个组件无缝协同支持。
    eg:
    Tom: “ 我把上次我们聚会的照片发你 mail ”
    Jack: “ok”,心想: 照片把我拍的太丑了,我要P一下,再发到 ….
    以上操作需要以下动作:
    ①在邮件app浏览图片
    ②分享到图片编辑app
    ③编辑修改图片
    ④分享到社交app
    完成以上动作,Android和PC交互对比:
    PC: 应用之间无关联,通过桌面+鼠标拖拽进行交互;
    Android: 没有“桌面+鼠标”,“应用”之间直接交互( 基于组件开发 : 通过四大组件和 Intent 进行交互 )

二、UI的基石——Activity

1.创建Activity

  • 创建XXActivity.java,继承Activity
  • 在AndroidManifest.xml里面注册
  • 编写布局xml
  • 在onCreate里面setContent(xml)

Intent: 四大组件中通讯的对象(启动Activity、Service、传递Broadcast等)
● Bundle: Intent中的“ 数据 ”,一个Map类型的KV包装类,封装了序列化操作
● Parcel: Android中的序列化方式,可用于跨进程传输

2.跳转与关闭

使用startActivity()进行跳转,使用Intent传递数据;

使用finish()退出Activity或者点击Back按键退出Acticity(默认内部也会调用到finish);

3.Activity生命周期

回调函数:
    ● onCreate、onDestroy
    ● onStart、onStop(当界面消失时,比如跳转至别的页面,stop)
    ● onResume、onPause(当出现透明主题时,比如焦点对话框等,pause)
    ● onRestart
特殊情况:
  • ​​​​onSaveInstanceState和onRestoreInstanceState(保存之前状态)

4.Intent相关

  • 显示Intent:明确了要指定启动的组件

 表示从当前界面跳转至XmlActicity

  • 隐示Intent:没有明确指定的组件,会把命中特定规则的组件都唤起然后选择

 比如要打开百度首页,只设置网页和动作,手机下方弹出所有的浏览器供用户选择。

  • startActivityForResult:启动一个新的Activity之后需要有返回值
模拟微信授权,腾讯后台会返回一个token值。

 三、基础UI组件

1.View和ViewGroup

  • 常见控件View

        TextView、Button、EditText、ImageView

  • 常见布局ViewGroup

        线性布局LinearLayout 、相对布局RelativeLayout 、帧布局FrameLayout

线性布局

 相对布局(相对于xx的位置)

帧布局 (写在越下面,则界面元素相对位于上面)

2.view的继承关系

 3.屏幕适配

3.1 基本概念

• px (像素)
• 分辨率:屏幕横向、纵向像素点,宽 x 高,如320 x 480
• 屏幕尺寸:屏幕对角线物理尺寸,单位英寸
• dpi (屏幕像素密度):每英寸像素点数
• dp (密度无关像素):保证不同屏幕像素屏幕上显示效果一致,Android特有
长度单位, 1dp = (dpi / 160) * 1px
• sp (独立比例像素):字体专用,其它和dp一样。区别是Android 自定义字体大
小功能,正常字体时 1sp = 1dp,超大、超小字体时 1sp 大于或者小于1dp
比如用px为单位时,当屏幕分辨率不同时,显示效果不同,而下方用dp作为单位是,显示效果没有变化。

3.2 相对布局

match-parent(与父容器大小一致)
wrap_content(与内容大小一致)

3.3 点九图——Nine Patch图

以.9.png为拓展名的png图片文件,可拉伸位图,适用于不定长内容背景(eg:聊天气泡)。

3.4 xxhpi xhpi hpi
根据屏幕密度对应目录下获取图片
        没有对应目录时:就近高密度 > 就近低密度
         没有对应目录时:图片自动根据当前密度进行缩放
eg:

 当前手机为xxhdpi,但是文件中最高密度只有xhdpi的图片,则从高到底查找,即xxhdpi中没有,则用xhdpi文件的图片。国内企业通常选择一个稍大密度的目录存放一份图片(减小apk包大小),原因:缩放不会失真,扩大可能会有一些失真。

四、事件传递

● 触摸事件(MotionEvent):ACTION_DOWN、ACTION_MOVE、ACTION_UP

● 事件分发(Dispatch):dispatchTouchEvent

● 事件拦截 (Intercept):onInterceptTouchEvent

● 事件消费 (Consume):onTouchEvent

eg: 

没当一个触摸事件到来,都是从 上往下执行分发,从下往上执行消费事件,即从Activity往View分发,如果有拦截事件则停止往下分发,回传执行消费事件,没有消费成功(消费事件的bool值为false时)往上回传给上一层消费,如果到最高层的Activity也没有消费,则该事件就被抛弃。

 五、高级UI组件

1.ListView

1.1 简介

一个显示可滚动项目的视图组件,系统使用Adapter(适配器)将列表项目插入列表,适配器从来源提取内容。在Android 5.0版本之后提供了RecycleView去替代ListView和GridView,提供了一种插拔式的体验,即模块化。

 1.2 ListView复用机制

采用MVC模式, 模型(model)-视图(view)-控制器 (controller)

M:model指要显示的数据,如封装数据的cursor,array等
V: view,就是listView用来显示封装好的数据
C: controller,就是adaptor,用来控制数据如何向listview中显示

     ps:引用自代码丶如风ActivityView其实就是在UI屏幕上可见的视图(onScreenView),也是与用户进行交互的View,那么这些View会通过RecycleBin直接存储到mActivityView数组当中,以便为了直接复用,那么当我们滑动ListView的时候,有些View被滑动到屏幕之外(offScreen) View,那么这些View就成为了ScrapView,也就是废弃的View,已经无法与用户进行交互了,这样在UI视图改变的时候就没有绘制这些无用视图的必要了。他将会被RecycleBin存储到mScrapView数组当中,但是没有被销毁掉,目的是为了二次复用,也就是间接复用。当新的View需要显示的时候,先判断mActivityView中是否存在,如果存在那么我们就可以从mActivityView数组当中直接取出复用,也就是直接复用,否则的话从mScrapView数组当中进行判断,如果存在,那么二次复用当前的视图,如果不存在,那么就需要inflate View了。


        如果数据源没有变化的时候,会从mActivityView数组中判断是否存在可以直接复用的View,举个例子,比如ListView一页可以显示10条数据,那么在这个时候滑动一个Item的距离,也就是把position = 0的Item移除屏幕,将position = 10 的Item移入屏幕,那么position = 1的Item是不是就直接能够从mActivityView数组中拿到呢?这是可以的,我们在第一次加载Item数据的时候,已经将position = 0~9的Item加入到了mActivityView数组当中,那么在第二次加载的时候,由于position = 1 的Item还是ActivityView,那么这里就可以直接从数组中获取,然后重新布局。这里也就表示的是Item的直接复用。        如果我们在mActivityView数组中获取不到position对应的View,那么就尝试从mScrapView废弃View数组中尝试去获取,当position = 0的Item被移除屏幕的时候,首先会Detach让View和视图进行分离,清空children,然后将废弃View添加到mScrapView数组当中,当加载position = 10的Item时,mActivityView数组肯定是没有的,也就无法获取到,同样mScrapView中也是不存在postion = 10与之对应的废弃View,就是mScrapView数组只有mScrapView[0]这一项数据,肯定是没有mScrapView[10]这项数据的,肯定是从Adapter中的getView方法获取新的数据,其实并不是这样,虽然mScrapView中虽然没有与之对应的废弃View,但是会返回最后一个缓存的View传递给convertview。那么也就是将mScrapView[0]对应的View返回。注意一种情况:比如说还是一页的Item,但是position = 0的Item没有完全滑动出UI,position = 10的Item没有完全进入到UI的时候,那么position = 0的Item不会被detach掉,同样不会被加入到废弃View数组,这时mScrapView是空的,没有任何数据,那么position = 10的Item即无法从mActivityView中直接复用View,因为是第一次加载。mActivityView[10]是不存在的,同时mScrapView是空的,因此position = 10的Item只能重新生成View,也就是从getView方法中inflate。

1.3 代码示例

①布局

适配器的代码: 

自定义一个适配器,继承自BaseAdapter,重写四个方法,getCount、getItem、getItemId、getView

public class ListBaseAdapter extends BaseAdapter {

    private static final int NUM_LIST_ITEMS = 100;

    // 数据集总个数
    @Override
    public int getCount() {
        return NUM_LIST_ITEMS;
    }

    // 根据position获取数据对象
    @Override
    public Object getItem(int position) {
        return null;
    }

    // 根据position获取数据对象的id
    @Override
    public long getItemId(int position) {
        return 0;
    }

    // 对应position的item数据展示样式view
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder = null;
        // 查看convertView是否为空,如果为空则重新创建,使用setTag方法实现保留复用
        if (convertView == null) {
            holder = new ViewHolder();
            convertView = View.inflate(parent.getContext(), R.layout.number_list_item, null);
            holder.listItemNumberView = (TextView) convertView.findViewById(R.id.tv_item_number);
            holder.viewHolderIndex = (TextView) convertView.findViewById(R.id.tv_view_holder_instance);
            convertView.setTag(holder);
        } else {
            // 复用机制,直接使用viewholder,无需每次都find id
            holder = (ViewHolder) convertView.getTag();
        }

        // 更新item对应的数据值
        holder.listItemNumberView.setText(String.valueOf(position));
        holder.viewHolderIndex.setText(String.format("ViewHolder index: %s", position));
        int backgroundColorForViewHolder = ColorUtils.
                getViewHolderBackgroundColorFromInstance(convertView.getContext(), position % 10);
        convertView.setBackgroundColor(backgroundColorForViewHolder);
        return convertView;
    }

    private static class ViewHolder {
        private TextView viewHolderIndex;
        private TextView listItemNumberView;
    }
}

③编写Activity,设置我们自己写的适配器。

public class ListViewActivity extends AppCompatActivity {
    private Toast mToast;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_listview);
        ListView listView = (ListView) findViewById(R.id.list_numbers);
        listView.setAdapter(new ListBaseAdapter());
        listView.setDivider(null);
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                if (mToast != null) {
                    mToast.cancel();
                }
                String toastMessage = "Item #" + position + " clicked.";
                mToast = Toast.makeText(ListViewActivity.this, toastMessage, Toast.LENGTH_LONG);
                mToast.show();
            }
        });
    }
}

注意: 在ListView中可以实现Click很简单,直接调用setOnItemClickListner,如上诉代码所示。

2 RecyclerView

2.1 RecyclerView简介

相比于ListView只能做上下滑动的视图,而RecyclerView可以灵活地使用包括线性布局(支持纵向、横向滑动)、网络布局、瀑布流。

 2.2 RecyclerView代码例子

①布局

 ②编写适配器

核心的方法:onCreateViewHolder、onBindViewHolder、getItemCount(类似于ListView中的getCount)

在ListView中,需要我们手动去实现ViewHolder,而在RecyclerView中将ViewHolder的方法接口暴露出来。

如果没有ViewHolder则通过onCreateViewHolder创建,有则调用onBindViewHolder在onBindViewHolder中通过我们自己写的bind函数设置相应的视图。

/**
 * 适配器
 */
public class GreenAdapter extends RecyclerView.Adapter<GreenAdapter.NumberViewHolder> {

    private static final String TAG = "GreenAdapter";

    private int mNumberItems;

    private final ListItemClickListener mOnClickListener;

    private static int viewHolderCount;

    public GreenAdapter(int numListItems, ListItemClickListener listener) {
        mNumberItems = numListItems;
        mOnClickListener = listener;
        viewHolderCount = 0;
    }


    /*
     * 一般会预留2~4个ViewHolder,off screen的数量由mCachedSize来决定
     *
     * The number of ViewHolders that have been created. Typically, you can figure out how many
     * there should be by determining how many list items fit on your screen at once and add 2 to 4
     * to that number. That isn't the exact formula, but will give you an idea of how many
     * ViewHolders have been created to display any given RecyclerView.
     *
     * Here's some ASCII art to hopefully help you understand:
     *
     *    ViewHolders on screen:
     *
     *        *-----------------------------*
     *        |         ViewHolder index: 0 |
     *        *-----------------------------*
     *        |         ViewHolder index: 1 |
     *        *-----------------------------*
     *        |         ViewHolder index: 2 |
     *        *-----------------------------*
     *        |         ViewHolder index: 3 |
     *        *-----------------------------*
     *        |         ViewHolder index: 4 |
     *        *-----------------------------*
     *        |         ViewHolder index: 5 |
     *        *-----------------------------*
     *        |         ViewHolder index: 6 |
     *        *-----------------------------*
     *        |         ViewHolder index: 7 |
     *        *-----------------------------*
     *
     *    Extra ViewHolders (off screen)
     *
     *        *-----------------------------*
     *        |         ViewHolder index: 8 |
     *        *-----------------------------*
     *        |         ViewHolder index: 9 |
     *        *-----------------------------*
     *        |         ViewHolder index: 10|
     *        *-----------------------------*
     *        |         ViewHolder index: 11|
     *        *-----------------------------*
     *
     *    index:12 from where?
     *
     *    Total number of ViewHolders = 12
     *
     *
     *    不做特殊处理:最多缓存多少个ViewHolder N(第一屏可见) + 2 mCachedSize + 5*itemType RecyclePool
     *
     *    找到position一致的viewholder才可以复用,新的位置由于position不一致,所以不能复用,重新创建新的
     *    这也是为什么 mCachedViews一开始缓存的是0、1    所以 8、9、10需要被创建,
     *    那为什么10 和 11也要被创建?
     *
     *    当view完全不可见的时候才会被缓存回收,这与item触发getViewForPosition不同,
     *    当2完全被缓存的时候,实际上getViewForPosition已经触发到11了,此时RecyclePool有一个viewholder(可以直接被复用)
     *    当12触发getViewForPosition的时候,由于RecyclePool里面有,所以直接复用这里的viewholder
     *    问题?复用的viewholder到底是 0 1 2当中的哪一个?
     *
     *
     *    RecycleView 对比 ListView 最大的优势,缓存的设计,减少bindView的处理
     */

    @NonNull
    @Override
    public NumberViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int viewType) {
        Context context = viewGroup.getContext();
        int layoutIdForListItem = R.layout.number_list_item;
        LayoutInflater inflater = LayoutInflater.from(context);
        boolean shouldAttachToParentImmediately = false;

        View view = inflater.inflate(layoutIdForListItem, viewGroup, shouldAttachToParentImmediately);
        NumberViewHolder viewHolder = new NumberViewHolder(view);

        viewHolder.viewHolderIndex.setText("ViewHolder index: " + viewHolderCount);

        int backgroundColorForViewHolder = ColorUtils
                .getViewHolderBackgroundColorFromInstance(context, viewHolderCount);
        viewHolder.itemView.setBackgroundColor(backgroundColorForViewHolder);

        Log.d(TAG, "onCreateViewHolder: number of ViewHolders created: " + viewHolderCount);
        viewHolderCount++;
        return viewHolder;
    }

    @Override
    public void onBindViewHolder(@NonNull NumberViewHolder numberViewHolder, int position) {
        Log.d(TAG, "onBindViewHolder: #" + position);
        numberViewHolder.bind(position);
    }

    @Override
    public int getItemCount() {
        return mNumberItems;
    }

    public class NumberViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {

        private final TextView viewHolderIndex;
        private final TextView listItemNumberView;

        public NumberViewHolder(@NonNull View itemView) {
            super(itemView);
            listItemNumberView = (TextView) itemView.findViewById(R.id.tv_item_number);
            viewHolderIndex = (TextView) itemView.findViewById(R.id.tv_view_holder_instance);
            itemView.setOnClickListener(this);
        }

        public void bind(int position) {
            listItemNumberView.setText(String.valueOf(position));


//            viewHolderIndex.setText(String.format("ViewHolder index: %s", getAdapterPosition()));
//            int backgroundColorForViewHolder = ColorUtils.
//                    getViewHolderBackgroundColorFromInstance(itemView.getContext(), getAdapterPosition() % 10);
//            itemView.setBackgroundColor(backgroundColorForViewHolder);
        }

        @Override
        public void onClick(View v) {
            int clickedPosition = getAdapterPosition();
            if (mOnClickListener != null) {
                mOnClickListener.onListItemClick(clickedPosition);
            }
        }
    }

    // 自定义接口
    public interface ListItemClickListener {
        void onListItemClick(int clickedItemIndex);
    }
}

③编写Activity

public class RecycleViewActivity extends AppCompatActivity implements GreenAdapter.ListItemClickListener {

    private static final String TAG = "wangyi";
    private static final int NUM_LIST_ITEMS = 100;

    private GreenAdapter mAdapter;
    private RecyclerView mNumbersListView;

    private Toast mToast;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_recycleview);
        mNumbersListView = findViewById(R.id.rv_numbers);

        // LinearLayoutManager布局管理,定义布局样式
        LinearLayoutManager layoutManager = new LinearLayoutManager(this);
        layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
        mNumbersListView.setLayoutManager(layoutManager);
        /*
         * Use this setting to improve performance if you know that changes in content do not
         * change the child layout size in the RecyclerView
         */
        mNumbersListView.setHasFixedSize(true);

        /*
         * The GreenAdapter is responsible for displaying each item in the list.
         */
        mAdapter = new GreenAdapter(NUM_LIST_ITEMS, this);

        mNumbersListView.setAdapter(mAdapter);
        mNumbersListView.addOnScrollListener(new RecyclerView.OnScrollListener() {

            // 最后一个完全可见项的位置
            private int lastCompletelyVisibleItemPosition;

            @Override
            public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
                RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
                int visibleItemCount = layoutManager.getChildCount();
                int totalItemCount = layoutManager.getItemCount();
                if (newState == RecyclerView.SCROLL_STATE_IDLE) {
                    if (visibleItemCount > 0 && lastCompletelyVisibleItemPosition >= totalItemCount - 1) {
                        Toast.makeText(RecycleViewActivity.this, "已滑动到底部!,触发loadMore", Toast.LENGTH_SHORT).show();
                    }
                }
            }

            @Override
            public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);
                RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
                if (layoutManager instanceof LinearLayoutManager) {
                    lastCompletelyVisibleItemPosition = ((LinearLayoutManager) layoutManager).findLastCompletelyVisibleItemPosition();
                }
                Log.d(TAG, "onScrolled: lastVisiblePosition=" + lastCompletelyVisibleItemPosition);
            }
        });
    }

    @Override
    public void onListItemClick(int clickedItemIndex) {
        Log.d(TAG, "onListItemClick: ");
        if (mToast != null) {
            mToast.cancel();
        }
        String toastMessage = "Item #" + clickedItemIndex + " clicked.";
        mToast = Toast.makeText(this, toastMessage, Toast.LENGTH_LONG);

        mToast.show();
    }
}

注意:在RecyclerView中默认没有像ListView中的点击方法。做法如下:

  • 在Activity中设置Adapter的时候会把我们自己定义的Listener传入。

  • 在Adapter中自定义一个onListItemClick的接口

 2.3 Adapter:

  • ItemView 复用Google已经搞定,不用再setTag
  • ViewHolder的编写规范化
        在实现Adapter的时候,我们一般会加上ViewHolder这个东西,ViewHolder和复用机制和原理是无关的,他的主要目的是持有Item中控件的引用,从而减少findViewById()的次数,因为findViewById()方法也是会影响效率的,因此在复用的时候他起的作用是这个,减少方法执行次数增加效率。

2.4 复用(三级缓存 + 自定义缓存):

3 ListView和RecyclerView对比

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/FengTingT/article/details/124221457

智能推荐

基于SSM的在线考试系统设计与实现_基于ssm的在线考试系统的设计与实现-程序员宅基地

文章浏览阅读1.5k次。系统展示技术框架 开发语言:Java; 后端框架:SSM; 持久层框架:MyBatis 前端技术:jQuery.js,js,CSS; 中间件:Tomcat(apache-tomcat-8.0.47); 数据库:MySQL5.7/mariadb-10.3.14-winx64; 开发工具:Eclipse,HeidiSQL/Navicat; 开发环境建议开发者使用以下环境,这样避免版本带来的问题 IDE:ecl_基于ssm的在线考试系统的设计与实现

计算机网络.第五节课.笔记.以太网、CSMA/CD、VLAN_10mbit/s以太网最小的争用期长度-程序员宅基地

文章浏览阅读993次,点赞3次,收藏2次。MAC地址 长度48位即物理地址/硬件地址,全1为数据链路层广播地址。无效MAC帧IEEE802.3:帧长度不是整数个字节;检验序列 FCS 查出差错;数据字段长度太大或太小。MAC帧格式目的地址 6Byte 源地址 6Byte 类型 2Byte 数据字段 46Byte~1500Byte FCS 4Byte其中:1500Byte是MTU。46是以太网最短帧长减去6+6+2+4=18Byte。LAN特点无线局域网标准IEEE 802.11。其地理范围和站点数目都有限。可以_10mbit/s以太网最小的争用期长度

机器学习笔记(2)——使用朴素贝叶斯算法过滤(中英文)垃圾邮件_朴素贝叶斯算法提取中文单词-程序员宅基地

文章浏览阅读9.9k次,点赞3次,收藏46次。在上一篇文章《使用朴素贝叶斯算法对文档分类详解》中,我们实现了用朴素贝叶斯算法对简单文档的分类,今天我们将利用此分类器来过滤垃圾邮件。1. 准备数据——文本切分之前算法中输入的文档格式为单词向量,例如['my', 'dog', 'has', 'flea', 'problems', 'help', 'please'],而实际情况中通常要处理的是文本(例如邮件),那么就要先将文本转换为词向量,..._朴素贝叶斯算法提取中文单词

JavaSE基础二十二:GUI编程下的Swing展示窗口、面板、标签等组件_swing显示-程序员宅基地

文章浏览阅读337次。一、Swing1.概述与AWT类似,Swing也是GUI的一部分,并且Swing是在AWT组件基础上构建的,它所提供的功能要比AWT提供的更为广泛既然Swing是在AWT基础上构建的,那么Swing中就包含AWT中的各种组件,只是形式略有区别,用法相同我们在使用Swing开发时,只需要很少的代码就可以利用其丰富、灵活的功能和模块化组件来创建更优雅的用户界面2.顶层容器使用Swing时,..._swing显示

E280 P0410故障修复-程序员宅基地

文章浏览阅读1.3k次。07款的E280、开了24万公里。于2021年5月5日出现发动机灯亮。到修理厂电脑检查右列气缸组二次空气喷射故障(功能链)P0410 ,这是第一次出现。由于经常给候车的丁总没有在,其他工程师只是将故障码清楚,说再观察观察。2021年5月16日 故障灯亮 P0410,送到修理厂,由丁总亲自检查![在这里插入图片描述](https://img-blog.csdnimg.cn/20210622114924979.png?x-oss-process=image/watermark,type_ZmFuZ3poZW_p0410

水花效果_unity 雨打地上的水花-程序员宅基地

文章浏览阅读4.6k次。当用到河流或者别的有水域存在的东西的时候,如果要对人物走在水面上添加一个水纹效果,或者东西掉落在水里边有个水花四溅的效果,这都需要粒子系统做出来的水花效果(waterEffect)的结合,首先是检测碰撞,然后是在碰撞点实例化一个waterEffect_unity 雨打地上的水花

随便推点

node部署后访问不了解决方案_node-red 启动网页不显示-程序员宅基地

文章浏览阅读2k次。centos,使用pm2部署node应用之后,发现访问不了,单独node启动也访问不了最后究其原因,端口被挡了。。。解决方法:$ /sbin/iptables -I INPUT -p tcp --dport 58089 -j ACCEPT执行后,可以访问了。。。记录之..._node-red 启动网页不显示

mysql5.7默认生成随机密码,不知道登录时需要强改_mysql 5.7 默认生成一个随机密码-程序员宅基地

文章浏览阅读5.8k次,点赞3次,收藏2次。其实想要重置 5.7 的密码很简单,就一层窗户纸:1、修改 /etc/my.cnf,在 [mysqld] 小节下添加一行:skip-grant-tables=1这一行配置让 mysqld 启动时不对密码进行验证2、重启 mysqld 服务:systemctl restart mysqld3、使用 root 用户登录到 mysql:mysql -u root _mysql 5.7 默认生成一个随机密码

【Leetcode刷题篇】leetcode46 全排列_leetcode 全排列js-程序员宅基地

文章浏览阅读234次。题目:给定一个 没有重复 数字的序列,返回其所有可能的全排列。示例:示例:输入: [1,2,3]输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]题解:回溯法package com.lcz.leetcode;import java.util.*;public class Leetcode46 { public List<List<Integer>> permute(int[] nums._leetcode 全排列js

数据库--Postgresql语法--date、年月日、时间类型整理_postgres date-程序员宅基地

文章浏览阅读5.3k次。1.时间表示pg中的LOCALTIMESTAMP(0),相当于oracle中的sysdate2.时间进行格式转换2.1 to_Char to_char(LOCALTIMESTAMP(0), 'YYYY-MM-DD HH24:MI:SS') as detect_time2.2 to_Date to_date('2018-03-12 18:47:35','yyyy-MM-dd') to_date(#{birthdate},'yyyy-MM-d..._postgres date

html中调用flex中的函数-程序员宅基地

文章浏览阅读164次。首先,第一点是在html中嵌入swf文件 如下,在html中插入语句 <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="100%" height="500px" id="mapFlas..._thml 调用flex

排列熵算法--用于时间序列信号的复杂度检测_时间序列复杂度-程序员宅基地

文章浏览阅读1.2w次,点赞17次,收藏146次。排列熵算法(Permutation Entropy PE)出发点:用于脑电信号的信号判别,提取该排列熵特征,以区分不同的类其它突变信号检测方法:总结:1、傅里叶变换在全局上提供了信号整体奇异性的描述, 无法指出局部对整体奇异性的贡献, 因此无法定位突变发生的具体时刻2、短时傅里叶变换在给定的时间间隔和频率间隔内效果比较明显, 但对所有的频率都使用单一的窗函数, 分辨率保持不..._时间序列复杂度

推荐文章

热门文章

相关标签