Android之Fragment简介和使用实例(1)

动态添加Fragment


上面我们已经通过XML方式成功将fragment嵌入到Activity中(这种嵌入方式我们称为静态添加),但这种添加方式依然不够灵活.于是Android提供了另一种更加灵活的添加方式,也是我们日常开发中用的最多的一种添加方式----动态添加。

动态添加顾名思义就是在程序运行时根据不同的情况动态地添加我们所需的fragment,下面我们将通过实例来学习如何动态添加Fragment。

自定义一个AddByDynamicActivity,并根据屏幕宽高的变化,动态添加AddFragmentFirst和AddFragmentSecond,代码如下:

public class AddByDynamicActivity extends Activity {

@SuppressLint(“NewApi”)

@Override

protected void onCreate(Bundle savedInstanceState) {

// TODO Auto-generated method stub

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_addbydynamic);

//获取屏幕宽高

DisplayMetrics mDisplayMetrics = new DisplayMetrics();

getWindowManager().getDefaultDisplay().getMetrics(mDisplayMetrics);

//1.根据上下文获取FragmentManager对象

FragmentManager manager = this.getFragmentManager();

if(mDisplayMetrics.widthPixels < mDisplayMetrics.heightPixels){

//2.使用获取到的manager对象开启一个事务

FragmentTransaction mFragmentTransaction01 = manager.beginTransaction();

//3.替换Fragment

mFragmentTransaction01.replace(R.id.container, new AddFragmentFirst());

//4.提交事务

mFragmentTransaction01.commit();

}else{

FragmentTransaction mFragmentTransaction02 = manager.beginTransaction();

mFragmentTransaction02.replace(R.id.container, new AddFragmentSecond()).commit();

}

}

}

AddByDynamicActivity的布局文件activity_addbydynamic的代码如下:

<LinearLayout

xmlns:android=“http://schemas.android.com/apk/res/android”

xmlns:tools=“http://schemas.android.com/tools”

android:layout_width=“match_parent”

android:layout_height=“match_parent”

android:id=“@+id/container”

android:orientation=“horizontal”

/>

AddFragmentFirst和AddFragmentSecond的代码沿用上面学习静态添加Fragment时的代码。编写完成后,我们运行一下程序,显示的运行界面如下图所示:

然后点击Ctrl + F11组合键(这里使用Android模拟器测试),程序显示的界面如下图所示:

根据上面的运行结果我们可知,我们已经成功完成了根据不同的情况动态地添加或替换不同的Fragment对象的测试。接下来我们就此来深入的学习一下动态添加Fragment的具体编码步骤以及需要注意的地方。

首先,要在Activity管理Fragment,我们需要使用Android API提供的FragmentManager类,我们可以通过Activity的getFragmentManager()方法获取FragmentManager对象,而要对Fragment进行添加、删除、隐藏或替换操作,则需对每个需要执行的操作开启一个事务(FragmentTransaction),我们可以通过FragmentManager对象的beginTransaction()方法开启。接着,我们可以根据具体需求使用add()、remove()、hide()或replace()方法来执行对Fragment的管理操作。最后,我们必须将每一个事务都提交到事务管理器中等待执行,Android提供了commit()和commitAllowingStateLoss()两个方法来执行事务提交,两个方法的区别是当使用commit()方法时,宿主Activity必须在保存它的状态(用户离开Activity)之前执行commit()提交操作,否则将会抛出一个异常,这是因为当activity再次被恢复时commit之后的状态将丢失。如果丢失也没关系,那么使用commitAllowingStateLoss()方法即可。这里需要注意的是,当事务提交完成后,事务并不会马上执行,而是由事务管理器安排的队列执行顺序,在必要时在宿主Activity的UI线程中执行。若不想等待要马上执行的话,可以在UI线程调用executePendingTransactions()来立即执行由commit()提交的事务. 但这么做通常不必要,除非事务是其他线程中的任务的一个从属。

依据上面的代码实例,我们下面来总结一下动态添加Fragment的具体步骤:

1、使用Activity的上下文对象的getFragmentManager()方法获取FragmentManager对象;

2、使用获取到的FragmentManager对象开启一个事务(FragmentTransaction),调用beginTransaction()方法执行事务开启;

3、使用开启的事务对象(FragmentTransaction)执行添加、隐藏、删除或替换(add()、hide()、remove() or replace())Fragment的操作;

4、调用commit()或commitAllowingStateLoss()方法执行事务的提交。

为Activity创建事件回调方法


在一些情况下,Fragment需要建立与宿主Activity或和同一宿主Activity的姊妹Fragment的通信来完成相关操作功能。Fragment一般可以调用getActivity()方法来访问宿主Activity实例,同样的,宿主Activity也可以调用FragmentManager类中的findFragmentById()或findFramentByTag()方法来得到Fragment的引用对象,并依此来调用Fragment中的方法。而要建立两个属于同一个Activity的Fragment对象的通信,则最好的方法就是借助宿主Activity这个桥梁来完成信息的传递,就比如上面讲的那个列表新闻显示的例子(FragmentA显示新闻标题列表,FragmentB显示新闻的详细内容),当我们点击FragmentA中的列表选项时,则需要将列表选项的值传递给FragmentB,以便FragmentB根据用户点击的列表项显示对应的新闻内容。下面我们将使用代码简单地实现新闻显示这个例子,加深对Fragment的了解。我们先整理一下实现思路:首先定义一个宿主Activity(例子名中为ActivityForCallBackActivity),主要用于装载新闻列表的Fragment(例子中名为ActivityForCallBackFragmentA)和显示新闻内容详细的Fragment(例子中名为ActivityForCallBackFragmentB),然后在ActivityForCallBackFragmentA中定义一个事件回调方法,并在宿主ActivityForCallBackActivity实现其回调接口,这里使用回调主要作用是用于监听用户点击新闻列表项的事件,接着在宿主ActivityForCallBackActivity使用getFragmentManager().findFragmentById()方法获取显示新闻内容详细(ActivityForCallBackFragmentB)的实例,并在实现的回调方法onArticleSelected()方法中调用ActivityForCallBackFragmentB中的setContent()用于设置从ActivityForCallBackFragmentA传递过来的新闻Title。好了,基本思路已经理清,下面看下具体实现的代码。

首先定义一个ActivityForCallBackActivity类作为两个Fragment的宿主Activity,该类的代码如下:

/**

  • @author AndroidLeaf

  • 该示例主要实现新闻阅读例子

*/

public class ActivityForCallBackActivity extends Activity implements OnArticleSelectedListener{

private ActivityForCallBackFragmentB mFragmentB;

@SuppressLint(“NewApi”)

@Override

protected void onCreate(Bundle savedInstanceState) {

// TODO Auto-generated method stub

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_activityforcallback);

//获取ActivityForCallBackFragmentB新闻详细内容对象

mFragmentB = (ActivityForCallBackFragmentB)

getFragmentManager().findFragmentById(R.id.activityforcallback_fragment_b);

}

@Override

public void onArticleSelected(int itemID,String title) {

// TODO Auto-generated method stub

//详细页显示新闻Title

mFragmentB.setContent(title);

}

}

布局文件activity_activityforcallback.xml的代码如下:


<LinearLayout

xmlns:android=“http://schemas.android.com/apk/res/android”

xmlns:tools=“http://schemas.android.com/tools”

android:layout_width=“match_parent”

android:layout_height=“match_parent”

android:orientation=“horizontal”

<fragment

android:layout_width=“0dp”

android:layout_weight=“1”

android:layout_height=“match_parent”

android:id=“@+id/activityforcallback_fragment_a”

android:name=“com.androidleaf.fragmentdemo.fragment.ActivityForCallBackFragmentA”

/>

<fragment

android:layout_width=“0dp”

android:layout_weight=“2”

android:layout_height=“match_parent”

android:id=“@+id/activityforcallback_fragment_b”

android:name=“com.androidleaf.fragmentdemo.fragment.ActivityForCallBackFragmentB”

/>

然后创建展示新闻列表的ActivityForCallBackFragmentA.java类,代码如下:

public class ActivityForCallBackFragmentA extends Fragment implements OnItemClickListener{

private ListView mListView;

ArrayAdapter adapter = null;

ArrayList list = null;

/**

  • 创建一个事件回调函数,用来监听用户点击列表选项的操作

*/

public OnArticleSelectedListener mArticleSelectedListener;

public interface OnArticleSelectedListener{

public void onArticleSelected(int itemID,String title);

}

@Override

public void onAttach(Activity activity) {

// TODO Auto-generated method stub

super.onAttach(activity);

try {

//将宿主Activity对象强制转换成OnArticleSelectedListener实例,主要是为了确保宿主Activity实现监听接口

mArticleSelectedListener = (OnArticleSelectedListener) activity;

} catch (ClassCastException e) {

// TODO: handle exception

throw new ClassCastException(activity.toString() + " must implement OnArticleSelectedListener");

}

}

@Override

public void onCreate(Bundle savedInstanceState) {

// TODO Auto-generated method stub

super.onCreate(savedInstanceState);

/**

  • 初始化新闻列表的值

*/

list = new ArrayList();

list.add(“a”);

list.add(“b”);

list.add(“c”);

list.add(“d”);

list.add(“e”);

list.add(“f”);

list.add(“g”);

adapter = new ArrayAdapter(getActivity(), android.R.layout.simple_list_item_1, android.R.id.text1, list);

}

@Override

public View onCreateView(LayoutInflater inflater, ViewGroup container,

Bundle savedInstanceState) {

// TODO Auto-generated method stub

View inView = inflater.inflate(R.layout.fragment_activityforcallback_a, container, false);

mListView = (ListView)inView.findViewById(R.id.callback_listview);

mListView.setAdapter(adapter);

mListView.setOnItemClickListener(this);

return inView;

}

@Override

public void onPause() {

// TODO Auto-generated method stub

super.onPause();

}

@Override

public void onItemClick(AdapterView<?> parent, View view, int position,

long id) {

// TODO Auto-generated method stub

//将选中的列表选项ID和Title传递给实现监听接口的宿主Activity

mArticleSelectedListener.onArticleSelected(position,list.get(position));

}

}

布局文件fragment_activityforcallback_a.xml的代码如下:

<RelativeLayout xmlns:android=“http://schemas.android.com/apk/res/android”

xmlns:tools=“http://schemas.android.com/tools”

android:layout_width=“match_parent”

android:layout_height=“match_parent”

android:id=“@+id/callback_a_container”

android:paddingBottom=“@dimen/activity_vertical_margin”

android:paddingLeft=“@dimen/activity_horizontal_margin”

android:paddingRight=“@dimen/activity_horizontal_margin”

android:paddingTop=“@dimen/activity_vertical_margin”

<ListView

android:layout_width=“match_parent”

android:id=“@+id/callback_listview”

android:layout_height=“wrap_content”

/>

接着创建显示详细新闻内容的ActivityForCallBackFragmentB.java类,代码如下:

public class ActivityForCallBackFragmentB extends Fragment{

private TextView mTextView;

@Override

public void onCreate(Bundle savedInstanceState) {

// TODO Auto-generated method stub

super.onCreate(savedInstanceState);

}

@Override

public View onCreateView(LayoutInflater inflater, ViewGroup container,

Bundle savedInstanceState) {

// TODO Auto-generated method stub

View inView = inflater.inflate(R.layout.fragment_activityforcallback_b, container, false);

mTextView = (TextView)inView.findViewById(R.id.callback_textview);

return inView;

}

@Override

public void onPause() {

// TODO Auto-generated method stub

super.onPause();

}

public void setContent(String titleContent){

if(!TextUtils.isEmpty(titleContent)){

mTextView.setText(titleContent);

}

}

}

布局文件fragment_activityforcallback_b.xml代码如下:

<RelativeLayout xmlns:android=“http://schemas.android.com/apk/res/android”

xmlns:tools=“http://schemas.android.com/tools”

android:layout_width=“match_parent”

android:layout_height=“match_parent”

android:background=“#FF0000”

android:paddingBottom=“@dimen/activity_vertical_margin”

android:paddingLeft=“@dimen/activity_horizontal_margin”

android:paddingRight=“@dimen/activity_horizontal_margin”

android:paddingTop=“@dimen/activity_vertical_margin”

<TextView

android:layout_width=“wrap_content”

android:layout_height=“wrap_content”

android:layout_centerInParent=“true”

android:textSize=“50sp”

android:textColor=“#000000”

android:id=“@+id/callback_textview”

/>

代码编写完成,接下来运行程序,效果图如下图示:

在Fragment中添加ActionBar

在Fragment添加ActionBar的方法其实和在Activity添加ActionBar的方法类似,在这里就不再赘述,需要了解ActionBar使用方法的读者,可以学习(ActionBar简介和使用实例)这篇文章。不过读者使用时需要注意的一点是,当用户在Fragment中选择一个菜单项时,其宿主Activity会首先接收到对应的回调.如果Activity的on-item-selected回调函数实现并没有处理被选中的项目, 然后事件才会被传递到Fragment的回调。在文章末尾提供下载的Demo中有关于在Fragment添加ActionBar的具体例子,由于较为简单,这里就不贴出代码,读者可以下载Demo来进行学习。

利用Fragment实现应用在手机和平板上的兼容实例

==================================================================================

Fragment起初是专门为了应用程序适配手机小屏幕和平板电脑大屏幕以达到应用在两者上运行能有最好的界面显示效果而设计的,例如对于屏幕尺寸较大的平板电脑,它有比一般手机设备更大的空间来显示更多的视图控件对象,那系统在运行应用时,当检测到是运行在较大屏幕尺寸的设备上时,系统将自动加载更大的屏幕界面布局,然后可以动态地添加Fragment来填充剩余的视图空间,最后实现更多的界面交互。不过由于Fragment有自己独立的生命周期,并可以在Activity中动态地被添加、删除或替换的特性,许多开发者在开发手机应用时也喜欢频繁使用Fragment来实现更加灵活的UI视图(即便应用不考虑或不需要在平板电脑上很好的显示界面)。下面我们通过一个新闻列表显示实例来学习如何使用Fragment来实现手机和平板的的适配,首先创建一个宿主Activity(例子中名为AdapterMobileAndPadActivity),主要用于装载Fragment和显示视图布局,代码如下:

public class AdapterMobileAndPadActivity extends Activity{

@SuppressLint(“NewApi”)

@Override

protected void onCreate(Bundle savedInstanceState) {

// TODO Auto-generated method stub

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_adaptermobile_and_pad);

}

}

布局文件activity_adaptermobile_and_pad分为两处地方,一个是在res/layout文件路径下,另一个是res/layout-land文件路径下,如下图所示:

res/layout/activity_adaptermobile_and_pad布局文件代码如下:

<LinearLayout xmlns:android=“http://schemas.android.com/apk/res/android”

xmlns:tools=“http://schemas.android.com/tools”

android:layout_width=“match_parent”

android:layout_height=“match_parent”

android:orientation=“horizontal” >

<fragment

android:layout_width=“0dp”

android:layout_weight=“1”

android:layout_height=“match_parent”

android:id=“@+id/adapter_article_list”

android:name=“com.androidleaf.fragmentdemo.fragment.AdapterArticleListFragment”

/>

res/layout-land/activity_adaptermobile_and_pad布局文件代码如下:

<LinearLayout

xmlns:android=“http://schemas.android.com/apk/res/android”

xmlns:tools=“http://schemas.android.com/tools”

android:layout_width=“match_parent”

android:layout_height=“match_parent”

android:orientation=“horizontal”

<fragment

android:layout_width=“0dp”

android:layout_weight=“1”

android:layout_height=“match_parent”

android:id=“@+id/adapter_article_list”

android:name=“com.androidleaf.fragmentdemo.fragment.AdapterArticleListFragment”

/>

<FrameLayout

android:layout_width=“0dp”

android:layout_weight=“3”

android:layout_height=“match_parent”

android:id=“@+id/details_container”

/>

两个文件夹中的同名布局文件分别为手机和平板界面的显示提供视图布局,当应用运行时,Android系统会根据当前运行环境来判断应用是否运行在大屏幕设备上,如果运行在大屏幕设备上,则加载res/layout-land下的布局文件,否则默认加载res/layout下的布局文件。关于动态加载界面布局的更多内容,可以学习( Android官方提供的支持不同屏幕大小的全部方法 )这篇文章。

接下来创建新闻列表显示界面的Fragment(例子中名为AdapterArticleListFragment),具体的代码如下:

public class AdapterArticleListFragment extends ListFragment{

/**

  • 判断当前加载的是否为大屏幕布局

*/

private boolean isScreenPad;

/**

  • 用来记录上次选中的项

*/

private int mCurrentPosition;

/**

  • 列表测试数据

*/

public static String[] articleTitles = {

“a”,“b”,“c”,“d”,“e”,“f”,“g”,

};

@Override

public void onCreate(Bundle savedInstanceState) {

// TODO Auto-generated method stub

super.onCreate(savedInstanceState);

}

@Override

public void onActivityCreated(Bundle savedInstanceState) {

// TODO Auto-generated method stub

super.onActivityCreated(savedInstanceState);

//绑定数据列表

setListAdapter(new ArrayAdapter<>(getActivity(), android.R.layout.simple_list_item_1, android.R.id.text1, articleTitles));

View details = getActivity().findViewById(R.id.details_container);

//检测是否使用大屏幕尺寸的布局

isScreenPad = details != null && details.getVisibility() == View.VISIBLE;

if(savedInstanceState != null){

//获取上次离开界面时列表选项值

mCurrentPosition = savedInstanceState.getInt(“currentChoice”, 0);

}

if(isScreenPad){

//设置列表选中的选项高亮

getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);

showDetails(mCurrentPosition);

}

}

@Override

public void onListItemClick(ListView l, View v, int position, long id) {

// TODO Auto-generated method stub

super.onListItemClick(l, v, position, id);

showDetails(position);

}

/**

  • 离开界面时保存当前选中的选项的状态值

*/

@Override

public void onSaveInstanceState(Bundle outState) {

// TODO Auto-generated method stub

super.onSaveInstanceState(outState);

outState.putInt(“currentChoice”, mCurrentPosition);

}

/**

  • @param index

*/

public void showDetails(int index){

mCurrentPosition = index;

if(isScreenPad){

getListView().setItemChecked(index, true);

AdapterArticleDetailFragment mDetailFragment = (AdapterArticleDetailFragment) getActivity().getFragmentManager().findFragmentById(R.id.details_container);

//若mDetailFragment为空或选中非当前显示的Fragment

if(mDetailFragment == null || mDetailFragment.showIndex() != index){

mDetailFragment = AdapterArticleDetailFragment.newInstance(index);

//替换Fragment实例对象

getActivity().getFragmentManager().beginTransaction().replace(R.id.details_container, mDetailFragment)

.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE)

.commit();

}

}else{

Intent mIntent = new Intent();

mIntent.setClass(getActivity(), AdapterArticleDetailActivity.class);

Bundle mBundle = new Bundle();

mBundle.putInt(“index”, index);

mIntent.putExtras(mBundle);

getActivity().startActivity(mIntent);

}

}

@Override

public void onPause() {

// TODO Auto-generated method stub

super.onPause();

}

}

然后创建新闻内容详细显示的Fragment(例子中名为AdapterArticleDetailFragment),具体的代码如下:

public class AdapterArticleDetailFragment extends Fragment{

private TextView titleContent;

public static int index;

/**

  • 实例化 AdapterArticleDetailFragment对象

  • @param index

  • @return AdapterArticleDetailFragment

*/

public static AdapterArticleDetailFragment newInstance(int index){

AdapterArticleDetailFragment mAdapterArticleDetailFragment = new AdapterArticleDetailFragment();

Bundle mBundle = new Bundle();

mBundle.putInt(“index”, index);

//保存当前选中的选项ID

mAdapterArticleDetailFragment.setArguments(mBundle);

return mAdapterArticleDetailFragment;

}

/**

  • 获取当前显示的选项ID

  • @return int index

*/

public int showIndex(){

if(getArguments() == null){

return 0;

}

return getArguments().getInt(“index”,0);

}

@Override

public void onCreate(Bundle savedInstanceState) {

// TODO Auto-generated method stub

super.onCreate(savedInstanceState);

}

@Override

public View onCreateView(LayoutInflater inflater, ViewGroup container,

Bundle savedInstanceState) {

// TODO Auto-generated method stub

View inView = inflater.inflate(R.layout.fragment_articledetails, container, false);

titleContent = (TextView)inView.findViewById(R.id.articledetails_textview);

//设置详情页的内容

titleContent.setText(AdapterArticleListFragment.articleTitles[getArguments().getInt(“index”,0)]);

return inView;

}

@Override

public void onPause() {

// TODO Auto-generated method stub

super.onPause();

}

}

布局文件fragment_articledetails的代码如下:

<RelativeLayout xmlns:android=“http://schemas.android.com/apk/res/android”

xmlns:tools=“http://schemas.android.com/tools”

android:layout_width=“match_parent”

android:layout_height=“match_parent”

android:background=“#FF0000”

android:paddingBottom=“@dimen/activity_vertical_margin”

android:paddingLeft=“@dimen/activity_horizontal_margin”

android:paddingRight=“@dimen/activity_horizontal_margin”

android:paddingTop=“@dimen/activity_vertical_margin”

<TextView

android:layout_width=“wrap_content”

android:layout_height=“wrap_content”

android:layout_centerInParent=“true”

android:textSize=“55sp”

android:textColor=“#000000”

android:id=“@+id/articledetails_textview”

/>

学习福利

【Android 详细知识点思维脑图(技能树)】

其实Android开发的知识点就那么多,面试问来问去还是那么点东西。所以面试没有其他的诀窍,只看你对这些知识点准备的充分程度。so,出去面试时先看看自己复习到了哪个阶段就好。

虽然 Android 没有前几年火热了,已经过去了会四大组件就能找到高薪职位的时代了。这只能说明 Android 中级以下的岗位饱和了,现在高级工程师还是比较缺少的,很多高级职位给的薪资真的特别高(钱多也不一定能找到合适的),所以努力让自己成为高级工程师才是最重要的。

这里附上上述的面试题相关的几十套字节跳动,京东,小米,腾讯、头条、阿里、美团等公司19年的面试题。把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节。

由于篇幅有限,这里以图片的形式给大家展示一小部分。

网上学习 Android的资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。希望这份系统化的技术体系对大家有一个方向参考。

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

android:paddingTop=“@dimen/activity_vertical_margin”

<TextView

android:layout_width=“wrap_content”

android:layout_height=“wrap_content”

android:layout_centerInParent=“true”

android:textSize=“55sp”

android:textColor=“#000000”

android:id=“@+id/articledetails_textview”

/>

学习福利

【Android 详细知识点思维脑图(技能树)】

[外链图片转存中…(img-whnIvr13-1714198305724)]

其实Android开发的知识点就那么多,面试问来问去还是那么点东西。所以面试没有其他的诀窍,只看你对这些知识点准备的充分程度。so,出去面试时先看看自己复习到了哪个阶段就好。

虽然 Android 没有前几年火热了,已经过去了会四大组件就能找到高薪职位的时代了。这只能说明 Android 中级以下的岗位饱和了,现在高级工程师还是比较缺少的,很多高级职位给的薪资真的特别高(钱多也不一定能找到合适的),所以努力让自己成为高级工程师才是最重要的。

这里附上上述的面试题相关的几十套字节跳动,京东,小米,腾讯、头条、阿里、美团等公司19年的面试题。把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节。

由于篇幅有限,这里以图片的形式给大家展示一小部分。

[外链图片转存中…(img-8EmRrgI4-1714198305724)]

网上学习 Android的资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。希望这份系统化的技术体系对大家有一个方向参考。

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

ASM字节码操作库---入门环境搭建

文章目录 概述环境配置demo尝鲜源码地址 概述 ASM是一个操作字节码的类库&#xff0c;提到字节码&#xff0c;很多人想到的首先是JAVA字节码。其实Kotlin,Groovy等语言也会生成字节码&#xff0c;并且和Java的字节码一样&#xff0c;都能被虚拟机识别执行&#xff0c;这就意味…

MATLAB无法识别汉字的问题解决方案

试了100种方法&#xff0c;都是不行。 期待的结果 应该是这样式的&#xff1a; feature(‘locale’) ans 包含以下字段的 struct: ctype: zh_CN.UTF-8collate: zh_CN.UTF-8time: zh_CN.UTF-8numeric: en_US_POSIX.UTF-8monetary: zh_CN.UTF-8messages: zh_CN.UTF-8encoding…

行为学学习记忆实验和抗焦虑实验两款硬件

安徽耀坤XWX-BM八臂迷宫实验&#xff08;Eight-arm Maze Test&#xff0c;RMT&#xff09;由八个完全相同的臂组成&#xff0c;这些臂从一个中央平台放射出来&#xff0c;所以又被称为放射迷宫。其基本方式是&#xff1a;训练动物受食物的驱使对迷宫的各臂进行探究&#xff0c;…

golang反射

go反射 反射基本介绍应用场景基本使用结构体注意练习最佳实践遍历结构体的方法&#xff0c;调用接头体的方法&#xff0c;获取结构体的标签 反射 基本介绍 反射可以在运行时动态获取变量的各种信息&#xff0c;比如变量的类型(type)、类别(kind)如果是结构体变量&#xff0c;…

【学习笔记二十九】EWM较特殊的业务场景

一、供应商寄售业务相关 1.创建寄售物料、寄售信息记录以及寄售的采购订单 2.创建交货单 3.维护入库交货 行项目里存在C寄售的标识 4.创建上架的仓库任务并确定 查看仓位库存&#xff0c;发现仓位库存里存在寄售标识C以及寄售库存所有方 5.寄售转自有 ①首先MIGO里进行寄…

Linux 权限与软件包管理器 yum

一. 研究Linux默认权限 目录 &#xff0c;起始权限&#xff1a;777 普通文件&#xff0c;起始权限666 Linux系统中存在权限掩码 使用umask指令也可以改变掩码 如果将掩码改为0000 我们可以看到权限发生改变&#xff08;重新设置掩码&#xff09; 最终权限起始权限 去掉 权限…

0426_C高级4

练习1&#xff1a; 输入一个数字&#xff0c;实现数字逆置&#xff08;不使用字符串截取方式&#xff09; 1 #!/bin/bash2 read -p "输入一个数字&#xff1a;" number3 p$number4 result5 while [ $p -ne 0 ]6 do7 result$((result*10p%10))8 p$((p/10))9 …

Python基础10-使用正则表达式进行文本处理

在编程过程中&#xff0c;我们经常需要对文本进行处理&#xff0c;以提取、替换或分割特定的字符串。正则表达式&#xff08;Regular Expression&#xff09;是一种强大的文本处理工具&#xff0c;它可以帮助我们实现这些任务。以下是使用正则表达式进行文本处理的一些基本方法…

react-lib 读取本地模板创建PDF

读取本地文件和读取远程的一样&#xff0c;都使用fetch去获取 async function modifyPdf() {let url ./template.pdflet existingPdfBytes await fetch(url).then(res > res.arrayBuffer()) // 这里也有问题要转一下const d new Uint8Array(existingPdfBytes)const pdfDo…

Mysql索引规范及原理分析

1 Mysql存储引擎 MySQL中的数据用各种不同的技术存储在文件中&#xff0c;每一种技术都使用不同的存储机制、索引技巧、锁定水平并最终提供不同的功能和能力&#xff0c;这些不同的技术以及配套的功能在MySQL中称为存储引擎。 存储引擎是MySQL将数据存储在文件系统中的存储方…

235 基于matlab的时频盲源分离(TFBSS)算法

基于matlab的时频盲源分离&#xff08;TFBSS&#xff09;算法&#xff0c;TFBSS用空间频率分布来分离非平稳信号&#xff0c;可以分离具有不同时频分布的源信号&#xff0c;也能够分离具有相同谱密度但时频分布不同的高斯源。同时&#xff0c;该算法在时频域上局域化源信号能量…

39岁TVB靓仔小生自曝恋情,曾沦为洗车工如今半年赚足7位数

39岁高钧贤自从2005年参加香港先生选举夺冠后&#xff0c;之后加入TVB拍摄过多套电视剧集&#xff0c;最近更有份参与《逆天奇案2》&#xff0c;日前他回到TVB电视城一厂与冯盈盈宣传剧集&#xff0c;更随即拍摄短片纪录放在网上分享&#xff0c;意外曝光TVB餐厅餐单&#xff0…

如何使用IDEA直接连接MySQL数据库

如何使用IDEA直接连接MySQL数据库 新建一个空项目打开DataBase窗口连接数据库第一次连接 需要先下载驱动上一步驱动下载太慢怎么办&#xff1f;下载好驱动后 测试连接 新建一个空项目 打开DataBase窗口 连接数据库 第一次连接 需要先下载驱动 如果这里下载的很慢 看下一步解决…

DaVinci Fusion Studio 19 for Mac/win:影视后期特效合成的巅峰之作

在影视后期制作的广袤天地里&#xff0c;一款强大的特效合成软件如同一位技艺高超的魔法师&#xff0c;能够化腐朽为神奇&#xff0c;将普通的影像素材转变为震撼人心的视觉盛宴。而DaVinci Fusion Studio 19&#xff0c;正是这样一款备受影视从业者推崇的巅峰之作。 无论是Ma…

矩阵按列相乘运算的并行化实现方法

这两天一直在琢磨如下矩阵计算问题。 已知dm矩阵X和hq矩阵Y&#xff0c;求如下矩阵&#xff1a; 其中X(:,i), Y(:,j)分别表示矩阵X, Y的第i列和第j列&#xff0c;易知Z为dh矩阵。 如果直接串行计算矩阵Z&#xff0c;两个循环共有mq&#xff0c;则会很慢&#xff0c;能不能并行化…

【b站李同学的Lee】Part 3 服务器开发 NodeJS+Gulp基础入门+实战

课程地址&#xff1a;【NodeJSGulp基础入门实战】 https://www.bilibili.com/video/BV1aE411n737/?share_sourcecopy_web&vd_sourceb1cb921b73fe3808550eaf2224d1c155 目录 9 服务器端基础概念 9.1 网站的组成 9.2 Node网站服务器 9.3 IP地址 9.4 域名 9.5 端口 9…

SCSS全局配置 vue项目(二)

目录 1、先要查看node版本 2、安装对应的node-sass、sass-loader版本 2.1根据项目使用的node版本安装对应的node-sass版本 2.2根据node-sass版本选择兼容的sass-loader版本&#xff0c;不然项目无法正常运行 3、在 vue.config.js 中配置&#xff1a; 4、在组件中…

刷题训练之前缀和

> 作者&#xff1a;დ旧言~ > 座右铭&#xff1a;松树千年终是朽&#xff0c;槿花一日自为荣。 > 目标&#xff1a;熟练掌握前缀和算法。 > 毒鸡汤&#xff1a;学习&#xff0c;学习&#xff0c;再学习 ! 学&#xff0c;然后知不足。 > 专栏选自&#xff1a;刷题…

物联网的基本功能及五大核心技术——青创智通

工业物联网解决方案-工业IOT-青创智通 物联网基本功能 物联网的最基本功能特征是提供“无处不在的连接和在线服务”&#xff0c;其具备十大基本功能。 &#xff08;1&#xff09;在线监测&#xff1a;这是物联网最基本的功能&#xff0c;物联网业务一般以集中监测为主、控制为…

Vitis HLS 学习笔记--C/C++ static 关键字的作用

目录 1. 简介 2. c/c共有性质 3. c独有性质 4. 示例说明 5. static 对于 HLS 工具的影响 6. 总结 1. 简介 在Vitis HLS中&#xff0c;偶尔会用到 static 关键字。考虑到Vitis HLS同时兼容C和C语言&#xff0c;有必要理解这两种语言中static关键字细微差异。本文旨在梳理…