带你一起走进ExpandListView的深入嵌套,实现不一样的城市选择

前面对ExpandListView进行了简单的介绍。如果您还没来得及学习ExpandListView的使用,可前往ExpandableListView的使用详解学习。前面只是对ExpandListView进行了简单的介绍,可能介绍完您会说so
easy。确实ExpandListView的用法就是这么简单。由于前面已经介绍过ExpandListView的使用,今天打算深入嵌套ExpandListView实现一个城市选择Demo。Demo的大概需求是这样的,点击省份展开其对应的城市列表,当当前城市列表是展开状态时点击其他省份不关闭城市列表而是直接更新到当前的省份的城市列表。其具体的效果图如下所示。

效果图

看到这张效果图(说明:由于这个布局上部分比较简单,这里我们主要对国内城市部分进行实现),你会作何感想呢?你可能会想,每行单独布局,每行下面默认的隐藏一个GridView,当点击的时候显示GridView否则不显示,当然这种方式肯定是能实现的。那用ExpandListView怎么来实现呢?

分析:

1. ExpandListView只有Group和Child,那怎么将其和ExpandListView结合起来呢?观察效果图发现,效果图中每一行就相当于一个Group,下面的列表就相当于一个Child。

2. Group和Child分别由什么组成呢?从效果图中可看出Group可由GridView或五个TextView组成(这里我们选择五个TextView),Child可由一个GridView组成。

Ok,上面的分析已经很到位了,不用说现在已经有一定的思路了,下面我们就对我们的设想进行实现,看到底能不能达到预期的效果。

第一步:配置相应的xml文件以及实体类(这里主要需要省名以及每个省名对应的城市名)

布局文件:

activity_main.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"
    android:gravity="center"
    tools:context=".MainActivity" >
    <ExpandableListView
        android:id="@+id/expandlistview"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#ffffff"
        android:cacheColorHint="#00000000"
        android:groupIndicator="@null"
        android:listSelector="#00000000" />
</LinearLayout>

group_item.xml文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="horizontal" >
    <TextView
        android:id="@+id/textAddress"
         android:layout_width="0dip"
         android:paddingTop="10dip"
         android:paddingBottom="10dip"
         android:layout_weight="1"
         android:gravity="center_vertical|center_horizontal"
         android:layout_height="wrap_content"
         android:text=""
        android:background="@drawable/press_down"
        />
     <TextView
        android:id="@+id/textAddress1"
          android:layout_width="0dip"
         android:layout_weight="1"
         android:paddingTop="10dip"
         android:paddingBottom="10dip"
           android:gravity="center_vertical|center_horizontal"
         android:layout_height="wrap_content"
         android:text=""
       android:background="@drawable/press_down"
        />
      <TextView
        android:id="@+id/textAddress2"
          android:layout_width="0dip"
         android:layout_weight="1"
          android:paddingTop="10dip"
         android:paddingBottom="10dip"
         android:layout_height="wrap_content"
           android:gravity="center_vertical|center_horizontal"
         android:text=""
          android:background="@drawable/press_down"
        />
       <TextView
        android:id="@+id/textAddress3"
           android:layout_width="0dip"
         android:layout_weight="1"
          android:paddingTop="10dip"
         android:paddingBottom="10dip"
         android:layout_height="wrap_content"
           android:gravity="center_vertical|center_horizontal"
         android:text=""
         android:background="@drawable/press_down"
        />
        <TextView
        android:id="@+id/textAddress4"
           android:layout_width="0dip"
         android:layout_weight="1"
         android:paddingTop="10dip"
         android:paddingBottom="10dip"
           android:gravity="center_vertical|center_horizontal"
         android:layout_height="wrap_content"
         android:text=""
         android:background="@drawable/press_down"
        />

</LinearLayout>

child_item.xml文件:(这里要使用自定义的GridView解决ExpandListView与GridView的冲突)

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
   >
    <com.example.testcitysearch.CustomGridView
        android:id="@+id/child_gridview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:numColumns="5"
        android:verticalSpacing="0dip"
        android:background="@color/main_divider"
        android:horizontalSpacing="0dip"
        android:stretchMode="columnWidth"
        android:gravity="center"
        />

</RelativeLayout>

grid_item.xml文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/main_divider"
    android:orientation="horizontal" >
    <TextView
        android:id="@+id/textAddress"
         android:layout_width="0dip"
         android:layout_weight="1"
         android:paddingTop="6dip"
         android:paddingBottom="6dip"
         android:gravity="center_vertical|center_horizontal"
         android:layout_height="wrap_content"
         android:text=""
        android:background="@drawable/bac_shape"
        />
</LinearLayout>

实体类:

GroupCountBean.java文件:

package com.example.testcitysearch;

import java.io.Serializable;
import java.util.List;
/**
 *
 * @author jamy
 *
 */
public class GroupCountBean implements Serializable{
	//组数
   public int groupcount;
   //所有组集合
   public List<GroupBean> list;
	public List<GroupBean> getList() {
		return list;
	}

	public void setList(List<GroupBean> list) {
		this.list = list;
	}
}

GroupBean.java文件:

package com.example.testcitysearch;

import java.io.Serializable;
import java.util.List;
/**
 *
 * @author jamy
 *每组元素属性
 */
public class GroupBean implements Serializable{
   //省份名字
   public String provincename;
   //子元素的个数
   public int childsize;
   //每一组中的子元素个数
   public int singleSize;
   public List<MemberBean> list;
	public List<MemberBean> getList() {
		return list;
	}

	public void setList(List<MemberBean> list) {
		this.list = list;
	}

}

MemberBean.java文件:

package com.example.testcitysearch;

import java.io.Serializable;
/**
 *
 * @author jamy
 *每个子元素的属性
 */
public class MemberBean implements Serializable{
  //标题
  public String title;
  //价格
  public String price;
  //二手价格
  public String secondPrice;
  //标志位
  public int flag;
}

第二步:编写相应的逻辑代码,其具体的MainActivity.java代码如下所示。

package com.example.testcitysearch;

import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.BaseExpandableListAdapter;
import android.widget.ExpandableListView;
import android.widget.ExpandableListView.OnGroupExpandListener;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity implements OnClickListener {
	private ExpandableListView mListView;
	// 每组的实体类对象
	private GroupBean mGroupBean;
	// 每个子元素的实体类对象
	private MemberBean mMemBean;
	// 存储一组数据
	private List<GroupBean> group_list;
	// 存储子数据
	private List<MemberBean> child_list;
	// 存储总共有多少组
	private List<GroupCountBean> groupcount_list;
	// flag作为每行的标记 flag=0 表示每行的第一个元素后面依次类推
	private int flag = -1;
	// 所有组实体类
	private GroupCountBean mGroupCountBean;
	// 每个省份所有的城市适配器
	private myAdapter adp = null;;
	// 设置每一行的其中的计数器,用于记录被点击的次数
	private int countOne = 0, countTwo = 0, countThree = 0, countFor = 0,
			countFiv = 0;
	// 用来临时寄存groupPosition的值
	private int groupTemp = -1;
	// ExpandListView 适配器
	private ExAdapter adapter;
	private Context mContext;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		initView();
	}

	/**
	 * 初始化控件
	 */
	private void initView() {
		mContext = MainActivity.this;
		// 存储总共有多少组
		groupcount_list = new ArrayList<GroupCountBean>();
		mListView = (ExpandableListView) findViewById(R.id.expandlistview);
		// 添加本地假数据
		addDatas();
		System.out.println(group_list.toString());
		// 扩展ListView Adapter
		adapter = new ExAdapter();
		mListView.setAdapter(adapter);

		/**
		 * 设置Group默认不展开
		 */
		mListView.setOnGroupExpandListener(new OnGroupExpandListener() {
			@Override
			public void onGroupExpand(int groupPosition) {
				System.out.println(groupPosition);
				for (int i = 0; i < groupcount_list.size(); i++) {
					if (groupPosition != i) {
						mListView.collapseGroup(i);
					}
				}
			}
		});

	}

	/**
	 * 添加本地数据
	 */
	private void addDatas() {
		/**
		 * 添加六组数据 k表示添加的Group数
		 */
		for (int k = 0; k < 6; k++) {
			// 新建GroupBean实体类
			mGroupCountBean = new GroupCountBean();

			// 存储每一组数据的集合
			group_list = new ArrayList<GroupBean>();

			mGroupCountBean.groupcount = 5;
			int temp = mGroupCountBean.groupcount;
			// group==0表示第一组,先测试第一组

			/**
			 * 每组中有五个子元素 i表示每组中子元素的个数
			 */
			for (int i = 0; i < temp; i++) {
				// 每个Group中的属性
				mGroupBean = new GroupBean();
				mGroupBean.provincename = "广东" + i;
				// 子孩子的数目
				mGroupBean.childsize = 8;
				int tep = mGroupBean.childsize;
				// 总的每一Group中的TextView数目
				mGroupBean.singleSize = 5;
				child_list = new ArrayList<MemberBean>();
				for (int j = 0; j < tep; j++) {
					// 定义每个childItem的实体类
					mMemBean = new MemberBean();
					mMemBean.title = "深圳" + k + "-" + i + "-" + j;
					// 将child对象添加到ChildList中
					child_list.add(mMemBean);
				}

				// 将child_list数据添加到GroupBean实体类中
				mGroupBean.setList(child_list);
				// 将mGroupBean数据添加到group_list集合中
				group_list.add(mGroupBean);
				System.out.println(child_list.toString());
			}

			// 向每组中添加数据
			mGroupCountBean.setList(group_list);
			// 将六组数据添加到组集合中
			groupcount_list.add(mGroupCountBean);
		}
	}

	/**
	 *
	 * @author Jamy 扩展ListView Adapter
	 */
	class ExAdapter extends BaseExpandableListAdapter {

		@Override
		public Object getGroup(int groupPosition) {

			return null;
		}

		@Override
		public int getGroupCount() {

			return groupcount_list.size();
		}

		@Override
		public long getGroupId(int groupPosition) {

			return groupPosition;
		}

		// 第一组
		@Override
		public View getGroupView(int groupPosition, boolean isExpanded,
				View convertView, ViewGroup parent) {
			View view = null;
			GroupHolder groupholder = null;
			if (convertView == null) {
				view = View.inflate(MainActivity.this, R.layout.group_item,
						null);
				groupholder = new GroupHolder();
				groupholder.mTextView = (TextView) view
						.findViewById(R.id.textAddress);
				groupholder.mTextView1 = (TextView) view
						.findViewById(R.id.textAddress1);
				groupholder.mTextView2 = (TextView) view
						.findViewById(R.id.textAddress2);
				groupholder.mTextView3 = (TextView) view
						.findViewById(R.id.textAddress3);
				groupholder.mTextView4 = (TextView) view
						.findViewById(R.id.textAddress4);
				groupholder.mTextView.setOnClickListener(MainActivity.this);
				groupholder.mTextView1.setOnClickListener(MainActivity.this);
				groupholder.mTextView2.setOnClickListener(MainActivity.this);
				groupholder.mTextView3.setOnClickListener(MainActivity.this);
				groupholder.mTextView4.setOnClickListener(MainActivity.this);
				view.setTag(groupholder);
			} else {
				view = convertView;
				groupholder = (GroupHolder) view.getTag();
			}
			int temp = 0;

			// groupholder.mTextView1.setTag(groupPosition);//设置group的标志
			// 设置第groupPosition组,第一个元素
			groupholder.mTextView.setTag(R.id.textAddress1, 0);
			groupholder.mTextView.setTag(R.id.textAddress2, groupPosition);
			// 设置第groupPosition组,第二个元素
			groupholder.mTextView1.setTag(R.id.textAddress1, 1);
			groupholder.mTextView1.setTag(R.id.textAddress2, groupPosition);
			// 设置第groupPosition组,第三个元素
			groupholder.mTextView2.setTag(R.id.textAddress1, 2);
			groupholder.mTextView2.setTag(R.id.textAddress2, groupPosition);
			// 设置第groupPosition组,第四个元素
			groupholder.mTextView3.setTag(R.id.textAddress1, 3);
			groupholder.mTextView3.setTag(R.id.textAddress2, groupPosition);
			// 设置第groupPosition组,第五个元素
			groupholder.mTextView4.setTag(R.id.textAddress1, 4);
			groupholder.mTextView4.setTag(R.id.textAddress2, groupPosition);
			// 设置对应的省名
			groupholder.mTextView.setText(group_list.get(temp).provincename);
			groupholder.mTextView1.setText(group_list.get(++temp).provincename);
			groupholder.mTextView2.setText(group_list.get(++temp).provincename);
			groupholder.mTextView3.setText(group_list.get(++temp).provincename);
			groupholder.mTextView4.setText(group_list.get(++temp).provincename);

			return view;
		}

		@Override
		public Object getChild(int groupPosition, int childPosition) {

			return null;
		}

		@Override
		public long getChildId(int groupPosition, int childPosition) {

			return childPosition;
		}

		/**
		 * 记得这里要设置为1,否则每组会出现多个相同的GridView
		 *
		 */
		@Override
		public int getChildrenCount(int groupPosition) {

			return 1;
		}

		@Override
		public boolean hasStableIds() {

			return true;
		}

		@Override
		public boolean isChildSelectable(int groupPosition, int childPosition) {

			return true;
		}

		@Override
		public View getChildView(final int groupPosition,
				final int childPosition, boolean isLastChild, View convertView,
				ViewGroup parent) {
			View view = null;
			ChildHolder childholder = null;
			if (convertView == null) {
				view = View.inflate(MainActivity.this, R.layout.child_item,
						null);
				childholder = new ChildHolder();
				childholder.mGridView = (CustomGridView) view
						.findViewById(R.id.child_gridview);
				view.setTag(childholder);
			} else {
				view = convertView;
				childholder = (ChildHolder) view.getTag();
			}

			// 传参数GroupPosition和flag,以方便对应的组和组中第一个元素查找
			adp = new myAdapter(groupPosition, flag);
			childholder.mGridView.setAdapter(adp);
			childholder.mGridView
					.setOnItemClickListener(new OnItemClickListener() {

						@Override
						public void onItemClick(AdapterView<?> arg0, View arg1,
								int arg2, long arg3) {
							GroupCountBean gb = groupcount_list
									.get(groupPosition);
							GroupBean sb = gb.getList().get(flag);
							String title = sb.getList().get(arg2).title;
							System.out.println(title + "------------->");
							Toast.makeText(mContext, title, Toast.LENGTH_SHORT)
									.show();
						}
					});
			return view;
		}

	}

	/**
	 * 每个省份所有的城市适配器
	 *
	 */
	class myAdapter extends BaseAdapter {
		private List<MemberBean> mDatas;// 定义一个中间变量存放每个省的数据
		int group;
		int temp;

		public myAdapter(int group, int index) {
			super();
			GroupCountBean gb = groupcount_list.get(group);
			GroupBean sb = gb.getList().get(index);
			mDatas = sb.getList();
			this.group = group;
			this.temp = index;
		}

		@Override
		public int getCount() {
			return mDatas == null ? 0 : mDatas.size();
		}

		@Override
		public Object getItem(int position) {
			return null;
		}

		@Override
		public long getItemId(int position) {
			return position;
		}

		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			View view = null;
			GroupHolder groupholder = null;
			if (convertView == null) {
				view = View.inflate(MainActivity.this, R.layout.group_item2,
						null);
				groupholder = new GroupHolder();
				groupholder.mTextView = (TextView) view
						.findViewById(R.id.textAddress);
				view.setTag(groupholder);
			} else {
				view = convertView;
				groupholder = (GroupHolder) view.getTag();
			}
			groupholder.mTextView.setText(mDatas.get(position).title);
			return view;
		}

	}
	/**
	 * 判断并处理Group的展开收缩以及数据更新
	 * @param isExpand
	 * @param count
	 * @param group
	 */
	private void HandleExpandEvent(boolean isExpand,int count,int group){
		if (isExpand) {
			if (count % 2 != 0) {
				mListView.collapseGroup(group);
				isExpand = false;
			} else {
				isExpand = true;
				adp.notifyDataSetChanged();
				adapter.notifyDataSetChanged();
			}
			isExpand = false;
		} else {
			isExpand = true;
			mListView.expandGroup(group);
		}
	}

	/**
	 * 1.flag作为每行的标记 flag=0 表示每行的第一个元素后面依次类推
	 * 2.用一个groupTemp临时变量来存放group的值,如果不同则将TextView所有的计数器的值设置为0
	 * 3.点击当前的TextView时将其他TextView的计数器设置为0
	 * 4.CountOne......CountFiv分别表示对应TextView点击的计数器
	 */
	@Override
	public void onClick(View v) {
		int Id = v.getId();
		boolean isExpand = false;
		int g = -1;
		// 每行中元素的下标
		flag = (Integer) v.getTag(R.id.textAddress1);
		//每行所在的下标
		g = (Integer) v.getTag(R.id.textAddress2);// Row num
		if (groupTemp != g) {
			groupTemp = g;
			//初始化计数模式
			setDefault();
		}
		//判断当前行是否展开
		isExpand = mListView.isGroupExpanded(g);
		switch (Id) {
		case R.id.textAddress:
			countTwo = 0;
			countThree = 0;
			countFiv = 0;
			countFor = 0;
			HandleExpandEvent(isExpand, countOne, g);
			countOne++;
			break;
		case R.id.textAddress1:
			countOne = 0;
			countThree = 0;
			countFiv = 0;
			countFor = 0;
			HandleExpandEvent(isExpand, countTwo, g);
			countTwo++;
			break;
		case R.id.textAddress2:
			countTwo = 0;
			countOne = 0;
			countFiv = 0;
			countFor = 0;
			HandleExpandEvent(isExpand, countThree, g);
			countThree++;
			break;
		case R.id.textAddress3:
			countTwo = 0;
			countThree = 0;
			countFiv = 0;
			countOne = 0;
			HandleExpandEvent(isExpand, countFor, g);
			countFor++;
			break;
		case R.id.textAddress4:
			countTwo = 0;
			countThree = 0;
			countOne = 0;
			countFor = 0;
			HandleExpandEvent(isExpand, countFiv, g);
			countFiv++;
			break;
		default:
			break;
		}
	}

	/**
	 * 每一个行Group包含五个TextView
	 */
	static class GroupHolder {
		// 每组中第一个TextView
		TextView mTextView;
		// 每组中第二个TextView
		TextView mTextView1;
		// 每组中第三个TextView
		TextView mTextView2;
		// 每组中第四个TextView
		TextView mTextView3;
		// 每组中第五个TextView
		TextView mTextView4;
	}

	/**
	 * 子元素是一个GridView
	 */
	static class ChildHolder {
		CustomGridView mGridView;
	}

	/**
	 * 初始化默认的点击次数
	 */
	private void setDefault() {
		countOne = 0;
		countTwo = 0;
		countThree = 0;
		countFor = 0;
		countFiv = 0;
	}

}

代码说明:

首先初始化控件加载对应的本地数据以及设置ExpandListView默认不展开,到此初始化的过程完毕。紧接着重点来了。开始设置对应的Adapter,设置前好好想想,需求是使Group中的五个TextView都可点击,并且点击不同的TextView显示不同的GridView,那咋们怎么知道点击的是哪个Group下的那个TextView呢?换言之说我们怎样将GroupPosition和对应的TextView的下标传到onClick()中呢?查找View的方法发现View有一个setTag()方法,由此我们的疑问就可迎刃而解了。在getGroupView()中分别将TextView所在的GroupPosition以及index设置进Tag里,在onClick()中获取GroupPosition以及TextView的index。这样点击关系就一一对应了。

下面是在Onclick()中加入相应的逻辑控制ExpandListView的展开以及对应数据更新。首先是获取对应的GroupPosition以及被点击TextView的index,初始化计数器(方便判断点击的次数,基数次点击展开Group,反之关闭Group)。判断当前Group是否展开,如果状态展开紧随判断是否是偶数次点击,偶数次则关闭Group,否则更新数据。当Group当前状态关闭,直接展开Group。由此ExpandListView实现城市选择的整体逻辑梳理清楚了。

下面看看其运行效果。

          

效果图

好了,ExpandListView完美实现了城市选择Demo。虽然看上去可能有点复杂,其实最关键的还是对应TextView点击事件的对应。虽然城市选择已经实现了,但当时在开发中确实遇到点问题,下面将本项目中需要注意的几点和大家说说。

1. getChildrenCount()这个方法必须返回1,不然会有每个Group中会有多个相同的GridView(因为这里我们是把每一行看成一个Group,每个TextView对应的其实都是同一个Child,所以这里只有一个Child)

2.一定要在getGroupView方法中设置TextView对应的GroupPositionu以及index,方便TextView的点击事件一一对应。

3.在设置GridView的Adapter时,需要传入GroupPosition和index,以方便设置对应TextView内容。

4.在onClick()中,处理事情之前必须将其他的计数器设置为0(比如:当前点击的是第一个TextView,则countTwo...countFiv都设置为0)。

好,以上就是鄙人用ExpandListView开发的一个简单的城市选择器,可能不是很完善,相当欢迎和大家一起多交流,如果您有好的建议,或者好的实现方式我可以向您讨教讨教。生活就在于不断折腾,想不到今天又时间写了两篇blog很开心。

4.4

时间: 2024-08-26 04:28:11

带你一起走进ExpandListView的深入嵌套,实现不一样的城市选择的相关文章

带着大家走进iOS单元测试世界

摘要 今天给大家着重介绍一下单元测试,很多人可能没有听过单元测试或者是只是听说过,而没有实际的去实践过,没有关系,今天就给大家普及普及这方面的知识,并且带着大家进行实践,切身体验一下单元测试好处. 如果一个移动端的开发人员对单元测试不去重视他,这种开发人员往往表现一种"无知的自信",总觉得自己写的代码质量很高,直到一次次虫子(Bug)把自己咬的头破血流时,出现重大问题时,才发现原来自己的代码已经到了剪不断理还乱的状态,而每一次修改一个bug,都需要走一遍"墨镜迷宫"

CabloyJS带你轻松走进NodeJS全栈开发-免费课程 作者亲授

课程说明 B站直播 为回馈新老同学对开源框架CabloyJS的支持与厚爱,快速而轻松的开启NodeJS全栈开发之旅.2019年9月5日至9月11日在B站开启了一波免费直播培训课程 课程信息,请点击链接 回放视频,请点击链接 网易云课堂 B站直播一共5节课,总时长约10小时.在将前2节课整理完回放视频之后,有网友建议将视频进一步切分,按知识点整理,从而便于按需观看和学习 因此,在中秋节3天假期,将所有回放视频重新整理,切分为112课时,并且已在网易云课程上线,同样是坚持免费盛筵 作者亲授 网易免费

走进京东金融:听过来人谈经验及技术干货

以「金融科技」定位的京东金融集团成立于2013年10月,逐步构建了供应链金融.消费金融.财富管理.众筹.证券.保险.支付.金融科技以及农村金融九大业务板块. 京东金融CEO陈生强表示,京东金融以数据为基础,以技术为手段,借力京东的场景和用户资源来做金融业务,这是自营金融业务.现在乃至未来,京东金融要做的是:遵从金融本质,以数据为基础,以技术为手段,为金融行业服务,从而帮助金融行业提升效率.降低成本.增加收入.这个定位就是金融科技. 京东金融这三年多,从无到有,从有到精,一路走来,背后定有许多精彩

马哥团队带你揭秘互联网巨头公司—阿里巴巴

继马哥团队腾讯一行之后,4月中旬我们又来到了坐落于杭州的另一个互联网巨头公司. 波涛万里长江水,带你入杭州. 真情伴你走,春色为你留. 西湖烟水茫茫,百顷风潭,十里荷香. 风景甚好,怎能不去杭州的阿里巴巴转转呢? 带着"淡妆",走,跟着我们前行-- 马哥更是笑道:"我们这次来是和马云谈合作的!让我们培训出来的更多同学能直接签约阿里,致力于打造更好的linux培训,为中国互联网贡献更多力量",我们一行瞬间动力十足. 一."行"成于思 千里之行,始于

MWeb 1.2 版更新说明和用 wkhtmltopdf 生成带目录的 PDF 和自定预览 CSS

新增 可选择在输入时是否自动插入列表编号,可以在 Preferences --> General --> Auto insert list and blockquote prefix 开启和关闭. 分享功能的 Copy as image.Save as image.Save as PDF 等现在统一都用HTML的样式了,另外还专门为分享到微薄等SNS生成的图片做了优化,比如说如果有代码,会强制换行. 新增把文档库里的单个或多个文档导出为HTML或者PDF.使用方法为:选择要导出的文档(可多选)

kvm嵌套虚拟化

KVM嵌套虚拟化 嵌套虚拟化指的是在宿主机上创建的虚拟机中,再运行hypervisor,从而在虚拟机里面再运行一个虚拟机,可以是KVM嵌套KVM,Xen嵌套Xen,或者是不同类型hypervisor的嵌套(如KVM嵌套Xen,VMware嵌套KVM等) 下面开始嵌套虚拟化的实验,我选择的类型是KVM  on KVM的嵌套 实验环境: 主机名 角色 KVM 宿主机 vm1 第一层虚拟机 vm1-1 第二层虚拟机 首先宿主机的内核版本需要3.0+,其次内核需要打开nested的功能,让内核支持嵌套虚

利用VS自带的dotfuscator混淆代码的学习

对于一些原创的敏感代码,我们可以通过简单的重命名混淆使得别人难以真正理解执行原理.这一点,使用VS自带的dotfuscator即可实现. 如上图所示,你可以自定义选择哪些类被排除重命名,内置的规则中,序列化变量都是被排除的. 并且有一点你可以大胆放心: 公用的所有字段.方法.属性.类名字都不会被重命名!也就是你混淆了一个DLL,不会影响其余程序调用它的. 其实大部分代码都是不用混淆重命名的,但是如果你有绝妙的代码组织,那的确是应该保护的!

放春假倒逼家长带薪休假遭质疑 有人呼吁先落实双休

国务院日前印发<关于促进旅游业改革发展的若干意见>,明确将带薪年休假制度落实情况纳入各地政府议事日程,并提出中小学可安排放春假,为职工落实带薪年休假创造条件. 避开或冷或热的寒暑假.人山人海的黄金周,在和煦的春光里跟孩子来一场说走就走的带薪休假,这样的前景令不少家长向往.然而对通过春假“刺激”带薪休假落实的质疑,与“孩子放假我却请不到假”的担忧,也随之弥漫. 质疑 “用春假‘倒逼’带薪休假,是本末倒置”? 听说未来中小学有可能放春假,每年有10天年假的张旭很是兴奋.4岁的儿子还没有上学,这两年

各品牌服务器的默认带外BMC管理地址

连接网段到sugon服务器的带外BMC管理端,在本地网络的属性中,选择ipv4更改使用固定IP地址10.0.0.5和默认的10.0.0.10为同一个网段, 然后在浏览器输入默认的地址:10.0.0.10 sugon TC6600   默认的带外管理地址 10.0.0.10   帐号:admin 密码:admin  (采用连接网线的方式) dell R930默认的带外管理地址: 192.168.0.120    帐号:root  密码:calvin  (采用连接网线的方式) H3C 设置带外管理的