Android 高级UI组件(二)
1、ExpandableListView
显示垂直滚动两级列表的条目,只允许两个层次
整体思路:
要给ExpandableListView设置适配器,那么必须先设置数据源。
数据源,就是此处的适配器类ExpandableAdapter,需要重写里面的几个方法
数据源中用到了自定义的View布局,此时根据自己的需求来设置组和子项的布局样式,getChildView()和getGroupView()方法设置自定义布局
<ExpandableListView
android:id="@+id/expand"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
expand.setAdapter(new MyExpandableAdapter());
expand.setOnGroupClickListener(new ExpandableListView.OnGroupClickListener() {
@Override
public boolean onGroupClick(ExpandableListView expandableListView, View view, int i, long l) { return false;
}
});
expand.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
@Override
public boolean onChildClick(ExpandableListView expandableListView, View view, int i, int i1, long l) {
Toast.makeText(MainActivity.this, childs[i][i1].toString(), Toast.LENGTH_SHORT).show();
return false;
}
}); expand.setOnGroupExpandListener(new ExpandableListView.OnGroupExpandListener() {
@Override
public void onGroupExpand(int groupPosition) { // 保证每次只展开一组
int count = expand.getExpandableListAdapter().getGroupCount(); for (int i = 0; i < count; i++) { if (groupPosition != i) { expand.collapseGroup(i);
}
}
}
});
//适配器
class MyExpandableAdapter extends BaseExpandableListAdapter { @Override
public int getGroupCount() {
return groups.length;
} @Override
public int getChildrenCount(int groupPosition) {
return childs[groupPosition].length;
} @Override
public Object getGroup(int groupPosition) {
return groups[groupPosition];
} @Override
public Object getChild(int groupPosition, int childPostion) {
return childs[groupPosition][childPostion];
} @Override
public long getGroupId(int groupPosition) {
return groupPosition;
} @Override
public long getChildId(int groupPosition, int childPostion) {
return childPostion;
} @Override
public boolean hasStableIds() {
return false;
} @Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = getLayoutInflater().inflate(R.layout.group_layout, null);
}
ImageView ime = (ImageView) convertView.findViewById(R.id.im_ex);
TextView tve = (TextView) convertView.findViewById(R.id.tv_ex);
tve.setText(groups[groupPosition]);
return convertView;
} @Override
public View getChildView(int groupPosition, int childPostion, boolean isLastChild, View convertView, ViewGroup viewGroup) {
if (convertView == null) {
convertView = getLayoutInflater().inflate(R.layout.child_layout, null);
}
ImageView imec = (ImageView) convertView.findViewById(R.id.im_exc);
TextView tvec = (TextView) convertView.findViewById(R.id.tv_exc);
tvec.setText(childs[groupPosition][childPostion]);
return convertView;
} //二级菜单是否能被选中
@Override
public boolean isChildSelectable(int groupPosition, int childPostion) { return true;
}
}
group_layout.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_vertical"> <ImageView
android:id="@+id/im_ex"
android:layout_width="64dp"
android:layout_height="64dp"
android:src="@drawable/pic1" /> <TextView
android:id="@+id/tv_ex"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="not Data"
android:textSize="18sp"/> </LinearLayout>
2、ImageSwitcher
ImageSwitcher是Android中控制图片展示效果的一个控件,如:幻灯片效果,粗略的理解就是ImageView的选择器
原理:ImageSwitcher有两个子View:ImageView,当左右滑动的时候,就在这个两个ImageView之间来回切换来显示图片
既然有两个ImageView,我们要创建两个ImageView给ImageSwitcher,创建ImageSwitcher是通过工厂来实现的:ViewFactory
<ImageSwitcher
android:id="@+id/imgs"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
public class MainActivity extends Activity implements ViewSwitcher.ViewFactory, View.OnTouchListener { private ImageSwitcher imgs;
private int[] images = {R.drawable.ic_welcome, R.drawable.iv_welcome, R.drawable.iv_welcome1, R.drawable.iv_welcome2};
private int index = 0; float startX = 0.0f;
float endX = 0.0f; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); imgs = (ImageSwitcher) findViewById(R.id.imgs);
imgs.setFactory(this);
imgs.setOnTouchListener(this); } @Override
public View makeView() {
ImageView imageView = new ImageView(this);
imageView.setImageResource(images[0]);
return imageView;
} //触屏事件
@Override
public boolean onTouch(View view, MotionEvent motionEvent) { //获取当前事件的动作
int action = motionEvent.getAction();
//按住屏幕
if (action == MotionEvent.ACTION_DOWN) {
startX = motionEvent.getX();
return true;
}
if (action == MotionEvent.ACTION_UP) {
endX = motionEvent.getX();
if (startX - endX > 20) {
index = index + 1 < images.length ? ++index : 0;
//添加动画
imgs.setInAnimation(this, android.R.anim.fade_in);
imgs.setInAnimation(this, android.R.anim.fade_out);
} else if (endX - startX > 20) {
index = index - 1 >= 0 ? --index : images.length - 1;
imgs.setInAnimation(this, android.R.anim.fade_in);
imgs.setInAnimation(this, android.R.anim.fade_out);
}
imgs.setImageResource(images[index]);
}
return true;
} }
3、Menu
创建选项菜单的步骤:
覆盖Activity的onCreateOptionMenu(Menu menu)方法,当菜单第一次北大开始调用
调用Menu的add()方法添加菜单项(MenuItem),同时可以调用MenuItem的setIcon()方法来为菜单项设置图标
当菜单项被选择是,覆盖Activity的onOptionsItemSelected(MenuItem item)响应事件
@Override
public boolean onCreateOptionsMenu(Menu menu) {
//方法1:直接加载menu布局,推荐使用
getMenuInflater().inflate(R.menu.menu_main, menu); } @Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.recycler) {
RecyclerActivity.openActivity(MainActivity.this);
} else if (id == R.id.mySql) {
MySqlActivity.openActivity(MainActivity.this);
}
return super.onOptionsItemSelected(item);
}
menu_main.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/recycler"
android:title="Recycler"
app:showAsAction="never" />
<item
android:id="@+id/mySql"
android:title="mySql"
app:showAsAction="never" />
</menu>
@Override
public boolean onCreateOptionsMenu(Menu menu) { //方法2:单个添加
//添加菜单项(参数:组ID没当前选项ID,排序,标题)
menu.add(0, 100, 1, "设置");
menu.add(0, 200, 2, "开始");
menu.add(0, 300, 3, "关闭");
return true;
} @Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == 100) {
Toast.makeText(this,"设置",Toast.LENGTH_SHORT).show();
}
return super.onOptionsItemSelected(item);
}
Context menu
顾名思义,与长下文有关,操作室需要长时间按住某个东西不放,出现菜单。
覆盖Activity的onCreateContextMenu(Menu menu)方法调用Menu的add()方法添加菜单项(MenuItem)
覆盖Activity的onContextItemSelected(MenuItem item)来响应事件
调用registerForContextMenu()方法来为视图注册上下文菜单。
public class MainActivity extends Activity {
private TextView text; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
text = (TextView) findViewById(R.id.text);
//注册上下文菜单到text组件
registerForContextMenu(text); } //创建上下文菜单
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
getMenuInflater().inflate(R.menu.menu_main, menu);
} //点击事件
@Override
public boolean onContextItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.recycler) {
text.setTextColor(Color.BLUE);
} else {
text.setTextColor(Color.RED);
}
return super.onContextItemSelected(item);
}
}
4.SearchView
SearchView是Android原生的搜索框控件,它提供了一个用户界面,用于用户搜索查询。
SearchView默认是展示一个search的icon,点击icon展开搜索框,如果你想让搜索框默认就展开,可以通过setIconifiedByDefault(false);实现。
SearchView属性
属性名称 | 相关方法 | 描述 |
android:iconifiedByDefault | setIconifiedByDefault(boolean) | 设置搜索图标是否显示在搜索框内 |
android:imeOptions | setImeOptions(int) | 设置输入法搜索选项字段,默认是搜索,可以是:下一页、发送、完成等 |
android:inputType | setInputType(int) | 设置输入类型 |
android:maxWidth | setMaxWidth(int) | 设置最大宽度 |
android:queryHint | setQueryHint(CharSequence) | 设置查询提示字符串 |
使用:
<SearchView
android:id="@+id/searchView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:iconifiedByDefault="false"
android:queryHint="请输入搜索内容" />
// 设置搜索文本监听
mSearchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
// 当点击搜索按钮时触发该方法
@Override
public boolean onQueryTextSubmit(String query) {
//操作
return true;
} // 当搜索内容改变时触发该方法
@Override
public boolean onQueryTextChange(String newText) { return false;
}
});
设置SearchView
mSearchView = (SearchView) findViewById(R.id.search);
/**
* 默认情况下, search widget是"iconified“的,只是用一个图标 来表示它(一个放大镜),
* 当用户按下它的时候才显示search box . 你可以调用setIconifiedByDefault(false)让search
* box默认都被显示。 你也可以调用setIconified()让它以iconified“的形式显示。
*/
mSearchView.setIconifiedByDefault(true);
/**
* 默认情况下是没提交搜索的按钮,所以用户必须在键盘上按下"enter"键来提交搜索.你可以同过setSubmitButtonEnabled(
* true)来添加一个提交按钮("submit" button)
* 设置true后,右边会出现一个箭头按钮。如果用户没有输入,就不会触发提交(submit)事件
*/
mSearchView.setSubmitButtonEnabled(true);
/**
* 初始是否已经是展开的状态
* 写上此句后searchView初始展开的,也就是是可以点击输入的状态,如果不写,那么就需要点击下放大镜,才能展开出现输入框
*/
mSearchView.onActionViewExpanded();
// 设置search view的背景色
mSearchView.setBackgroundColor(0x22ff00ff);
/**
* 默认情况下, search widget是"iconified“的,只是用一个图标 来表示它(一个放大镜),
* 当用户按下它的时候才显示search box . 你可以调用setIconifiedByDefault(false)让search
* box默认都被显示。 你也可以调用setIconified()让它以iconified“的形式显示。
*/
mSearchView.setIconifiedByDefault(true);
配置监听器
mSearchView.setOnQueryTextListener(new OnQueryTextListener() { private String TAG = getClass().getSimpleName(); /*
* 在输入时触发的方法,当字符真正显示到searchView中才触发,像是拼音,在输入法组词的时候不会触发
*/
@Override
public boolean onQueryTextChange(String queryText) {
Log.d(TAG, "onQueryTextChange = " + queryText);
return true;
} /*
* 输入完成后,提交时触发的方法,一般情况是点击输入法中的搜索按钮才会触发。表示现在正式提交了
*/
@Override
public boolean onQueryTextSubmit(String queryText) {
Log.d(TAG, "onQueryTextSubmit = " + queryText); if (mSearchView != null) {
// 得到输入管理对象
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
if (imm != null) {
// 这将让键盘在所有的情况下都被隐藏,但是一般我们在点击搜索按钮后,输入法都会乖乖的自动隐藏的。
imm.hideSoftInputFromWindow(mSearchView.getWindowToken(), 0); // 输入法如果是显示状态,那么就隐藏输入法
}
mSearchView.clearFocus(); // 不获取焦点
}
return true;
}
});
在ActionBar上使用SearchView
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/search"
android:title="@string/search"
android:icon="@drawable/ic_menu_search"
android:showAsAction="collapseActionView|ifRoom"
android:actionViewClass="android.widget.SearchView" />
</menu>
public boolean onCreateOptionsMenu(Menu menu) { super.onCreateOptionsMenu(menu);
getMenuInflater().inflate(R.menu.search, menu); MenuItem search = menu.findItem(R.id.action_search);
/**
* 初始是否已经是展开的状态
* 写上此句后searchView初始展开的,也就是是可以点击输入的状态,如果不写,那么就需要点击下放大镜,才能展开出现输入框
*/
search.collapseActionView();
SearchView searchview = (SearchView) MenuItemCompat.getActionView(search);
searchview.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
lvJxwh.requestFocus();
srch_bt = query;
request();
return true;
} @Override
public boolean onQueryTextChange(String newText) {
return false;
}
}); return true;
}
5、弹出式菜单
弹出菜单是停靠在一个View上的模式菜单。如果View对象下方有空加,那么弹出菜单将显示在停靠对象的下方,否则会显示在上方。
public class MainActivity extends Activity {
private Button btn; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn = (Button) findViewById(R.id.btn); btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//创建弹出式菜单
PopupMenu popupMenu = new PopupMenu(MainActivity.this, view);
MenuInflater inflater = popupMenu.getMenuInflater();
inflater.inflate(R.menu.menu_main, popupMenu.getMenu());
popupMenu.show(); //设置点击事件
popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem menuItem) {
switch (menuItem.getItemId()) {
case R.id.recycler:
Toast.makeText(MainActivity.this, "recycler", Toast.LENGTH_SHORT).show();
break;
case R.id.mySql:
Toast.makeText(MainActivity.this, "mySql", Toast.LENGTH_SHORT).show();
break;
}
return false;
}
});
}
}); } }
6、ViewPager
VeiwPager 是一个ViewGroup,可以包含很多的View,当手指在屏幕上左右滑动的时候,可以切换界面。可以做很多事情,从最简单的导航,到页面菜单等。用法与ListView类似,也需要一个适配器,就是PagerAdapter。
ViewPager一般与Fragment结合使用比较方便。
ViewPager+Fragment可以做出多页面滑动的效果,让我们的应用程序界面操作起来更加灵活
ViewPager滑动事件讲解:
首先ViewPager在处理滑动事件时要用到OnPageChangeListener
OnPageChangeListener这个接口需要实现三个方法:(onPageScrollStateChanged,onPageScrolled ,onPageSelected)
onPageScrollStateChanged(int arg0) ,此方法是在状态改变的时候调用,其中arg0这个参数有三种状态(0,1,2)。arg0 ==1的时表示正在滑动,arg0==2的时表示滑动完毕了,arg0==0的时表示什么都没做。
onPageScrolled(int arg0,float arg1,int arg2) ,当页面在滑动的时候会调用此方法,在滑动被停止之前,此方法回一直得到调用。其中三个参数的含义分别为:
arg0 :当前页面,及你点击滑动的页面
arg1:当前页面偏移的百分比
arg2:当前页面偏移的像素位置
onPageSelected(int arg0) :此方法是页面跳转完后得到调用,arg0是你当前选中的页面的Position(位置编号)。
一、使用ViewPager
ViewPager的使用与ListView使用类似,也要绑定相应的适配器。
ViewPager的使用主要分3个步骤:
1、在布局文件中添加ViewPager控件。注意:写这个控件的时候要写全称(包名+类名)
<android.support.v4.view.ViewPager
android:id="@+id/main_viewPager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@+id/rg">
<android.support.v4.view.PagerTabStrip
android:id="@+id/pagertab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="top" />
</android.support.v4.view.ViewPager>
PagerTabTrip要当做ViewPager的一个子标签来用,可以用android:layout_gravity=TOP|BOTTOM来制定title的位置,如果要显示出PagerTabTrip的某一项Title,需要在ViewPager的Adapter中实现getPageTitle(int)。
instantiateItem(ViewGroup,int)//实例化页卡 destroyItem(ViewGroup,int,Object)//删除页卡 getCount()//返回页卡的数量 isViewFromObject(View,Object)//判断两个对象是否相等 getPageTitle(int position)//设置标签显示的标题
设置指示标签的属性:
pagerTabStrip.setTabIndicatorColor();//指示器的颜色 pagerTabStrip.setBackgroundColor();//背景色 pagerTabStrip.setTextColor(Color.WHITE);//设置字体颜色
2、加载要显示的界面,并把要显示的页面放入数组或List集合中
LayoutInflater lf = getLayoutInflater().from(this); view1 = lf.inflate(R.layout.layout1, null); view2 = lf.inflate(R.layout.layout2, null); view3 = lf.inflate(R.layout.layout3, null); viewList = new ArrayList<View>(); viewList.add(view1); viewList.add(view2); viewList.add(view3);
3、在Activity里实例化ViewPager组件,并设置它的Adapter,一般需要重写PagerAdapter。(和ListView使用差不多,使用步骤也类似。)
ViewPager的方法:
- setAdapter():ViewPager通过setAdapter()来建立与PagerAdapter的联系。这个联系是双向的,一方面,,ViewPager会拥有PagerAdapter对象,从而可调用PagerAdapter的方法,另一方面,ViewPager会在setAdapter()中调用PagerAdapter的registerDataSetObserver()方法,注册一个自己生成的PagerObserver 对象,从而在 PagerAdapter 有所需要时(如 notifyDataSetChanged() 或 notifyDataSetInvalidated() 时),可以调用 Observer 的 onChanged() 或 onInvalidated() 方法,从而实现 PagerAdapter 向 ViewPager 方向发送信息。
dataSetChanged():在 PagerObserver.onChanged(),以及 PagerObserver.onInvalide() 中被调用。因此当 PagerAdapter.notifyDataSetChanged() 被触发时,ViewPager.dataSetChanged() 也可以被触发。该函数将使用 getItemPosition() 的返回值来进行判断,如果为 POSITION_UNCHANGED,则什么都不做;如果为 POSITION_NONE,则调用 PagerAdapter.destroyItem() 来去掉该对象,并设置为需要刷新 (needPopulate = true) 以便触发 PagerAdapter.instantiateItem() 来生成新的对象。
二、PagerAdapter
PagerAdapter是ViewPager的支持者,ViewPager将调用它来取得所需展示的页面,而PagerAdapter也会在数据变化时通知ViewPager。这个类也是FragmentPagerAdapter以及FragmentStatePagerAdapter的基类。如果继承此类,至少需要实现instantiateItem(),destroyItem(),getCount()以及isViewFromObject()四个方法。
- instantiateItem():在每次ViewPager需要一个用以显示Object的时候,该方法都会被ViewPager.addNewItem()方法调用。该方法内部一定要把指定位置要显示的视图添加到ViewPager中。
- destroyItem():从当前的ViewPager容器中删除指定位置的View对象。
- getCount():返回要滑动的View的个数。
- isViewFromObject():该方法用来判断instantiateItem(ViewGroup , int)函数所返回来的key与一个页面视图是否是代表的同一个视图(即他俩是否是对应的,对应的表示同一个view) 返回值:如果对应的是同一个View,返回ture,否则返回false
三、ViewPager添加标题
- 给ViewPager添加一个子标签
<android.support.v4.view.PagerTitleStrip
android:id="@+id/pagerTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="top"/>
2.覆写PagerAdapter的getPageTitle(position)方法,该方法返回每个界面的title
- @Override
- public CharSequence getPageTitle(int position){}
注意:还有一种标题是android.support.v4.view.PagerTabStrip用法与上面的完全一样,唯一区别就是每个标题下面添加了一个下划线,并且标题也可点击
四、给ViewPager添加监听器OnPageChageListner
pager.setOnPageChangeListener(new OnPageChangeListener() {
/**
* 当滑动结束后,新的pager完全显示到屏幕后会调用该方法
* 参数:新的pager的index
*/
@Override
public void onPageSelected(int arg0) {
// Log.e(TAG, "onPageSelected..." + arg0);
} /**
* 当正在滑动时,会一直回调该方法
* arg0 :当前页面,及你点击滑动的页面
* arg1:当前页面偏移的百分比
* arg2:当前页面偏移的像素位置
*/
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
// Log.e(TAG, "onPageScrolled..." + arg0 + " " + arg1 + " " + arg2);
}
/**
* 当状态方法改变的时候调用
* 参数:页面的状态
* 共有三种状态:
* SCROLL_STATE_IDLE 页面静止的时候的状态
SCROLL_STATE_DRAGGING 正在滑动的状态
SCROLL_STATE_SETTLING 到了要滑动的最终位置的状态
*/
@Override
public void onPageScrollStateChanged(int arg0) {
//
String msg = "";
switch (arg0) {
case ViewPager.SCROLL_STATE_DRAGGING:
msg = "正在滑动";
break;
case ViewPager.SCROLL_STATE_IDLE:
msg = "静止了";
break;
case ViewPager.SCROLL_STATE_SETTLING:
msg = "到了";
break; default:
break;
}
Log.e(TAG, "onPageScrollStateChanged..." + msg);
}
});
Android 高级UI组件(二)的更多相关文章
- Android 高级UI组件(三)
一.popupWindow 1.AlertDialog和PopupWindow最关键的区别是AlertDialog不能指定显示位置,只能默认显示在屏幕最中间(当然也可以通过设置WindowManage ...
- Android 高级UI组件(一)GridView与ListView
1.GridView 1.GridView学习 GridView和ListView都是比较常用的多控件布局,而GridView更是实现九宫图的首选 main.xml: <?xml version ...
- Android常见UI组件之ListView(二)——定制ListView
Android常见UI组件之ListView(二)--定制ListView 这一篇接上篇.展示ListView中选择多个项及实现筛选功能~ 1.在位于res/values目录下的strings.xml ...
- Android 高级UI设计笔记07:RecyclerView 的详解
1. 使用RecyclerView 在 Android 应用程序中列表是一个非常重要的控件,适用场合非常多,如新闻列表.应用列表.消息列表等等,但是从Android 一出生到现在并没有非常 ...
- Android 高级UI设计笔记08:Android开发者常用的7款Android UI组件(转载)
Android开发是目前最热门的移动开发技术之一,随着开发者的不断努力和Android社区的进步,Android开发技术已经日趋成熟,当然,在Android开源社区中也涌现了很多不错的开源UI项目,它 ...
- Android之UI编程(二):表格布局
表格布局(TableLayout)继承了LinearLayout,它的本质依然是线性布局管理器,表TableLayout采用行.列的形式来管理UI组件,它并不需要明确地声明暴行多少行.多少列,而是通过 ...
- Android 基础UI组件(二)
1.Spinner 提供一个快速的方法来从一组值中选择一个值.在默认状态Spinner显示当前选择的值.触摸Spinner与所有其他可用值显示一个下拉菜单,可以选择一个新的值. /** * 写死内容: ...
- Android用户界面 UI组件--TextView及其子类(二) Button,selector选择器,sharp属性
1.XML文件中的OnClick 属性可以指定在Activity中处理点击事件的方法,Activity中必须定义该属性指定的值作为方法的名字且有一个View类型的参数,表示此物件被点击. 2.使用se ...
- Android 高级UI设计笔记01:使用ExpandableListView组件(ListView的扩展)
1.ExpandableListView是一个用来显示二级节点的ListView. 比如如下效果的界面: 2.使用ExpandableListView步骤 (1)要给ExpandableListVie ...
随机推荐
- 让 AI 为你写代码 - 体验 Github Copilot
前几天在群里看到有大神分享 Copoilot AI 写代码,看了几个截图有点不敢相信自己的眼睛.今天赶紧自己也来体验一下 Copoilot AI 写代码到底有多神奇. 申请 现在 Copoilot 还 ...
- 从拥有一个阿里云账号开始使用Maxcompute
本教程并不会创建子账户来管理maxcompute,是直接使用主账号来对maxcompute进行管理(强烈不推荐在生产环境中这样做!!) Step1:创建阿里云账号并实名认证 创建一个阿里云账号(使 ...
- SpringMVC配置版到注解版
什么是springmvc? 1.1.什么是MVC MVC是模型(Model).视图(View).控制器(Controller)的简写,是一种软件设计规范. 是将业务逻辑.数据.显示分离的方法来组织代码 ...
- 好好的 Tair 排行榜不用,非得自己写?20 行代码实现高性能排行榜
TairZset 是阿里云自研的可实现任意维度 double 类型的分值排序的数据结构,借助 Tair 客户端同时可实现扩展性,即可以将计算任务分布至多个数据节点完成,实现分布式排行榜能力.本文介绍了 ...
- 7-7 后缀式求值 (25分)的python实现
exp=input().split() ls=list() def Cal(a,b,i): if i=="+": return a+b elif i=="-": ...
- Buildroot 用户手册 (中文)
文章目录 I. Getting started 1. About Buildroot 2. System requirements 2.1. Mandatory packages 2.2. Optio ...
- 2021 数字四川创新大赛WriteUp
数字四川初赛+复赛wp Web easyphp http://111.9.220.114:50006/.index.php.swp 备份文件泄漏 <?php #error_reporting(0 ...
- c++学习笔记7(面向对象的程序设计)
面向对象的程序=类+类+....+类 设计程序的过程,就是设计类的过程 实例 对象的内存分配 对象间的运算 使用类的成员变量和成员函数
- Django 小实例S1 简易学生选课管理系统 8 CSS样式优化
Django 小实例S1 简易学生选课管理系统 第8节--CSS样式优化 点击查看教程总目录 作者自我介绍:b站小UP主,时常直播编程+红警三,python1对1辅导老师. 前面的几节下来,用户模块基 ...
- Python介绍和安装
python介绍和安装 目录 python介绍和安装 1. Python简介 2. 解释器 2.1 Python解释器的种类 2.2 Python解释器版本 3. Windows下安装Python 3 ...