Android — 长按ListView 利用上下文菜单(ActionMode) 进行批量事件处理

ListView:单击和长按弹出上下文菜单(ContextMenu) NULL 博文链接:https://pop1030123.iteye.com/blog/1125664 立即下载

好久没写博客拉```````

最近终于稍微闲一点了```````

无聊拿手机清理短信,发现批量事件的处理还是挺管用的``````

那么自己也来山寨一记看看效果吧`````


闲话少说,首先,我们来看下手机自带的短信功能里执行批量删除时的效果:



然后  是我们自己简单山寨的效果:

     


模拟的操作过程很简单,但也很有代表性。

我们假定我们所处的场景为,进入一个存放联系人列表的界面。


于是,首先我们定义了一个进度框,模拟提示正在从网络上下载数据。

接着,当网络数据成功下载到移动设备上后,将数据绑定显示到对应的ListView之中。

然后,就是我们这篇博客提到的:长按该联系人列表的ListView触发事件,

弹出使用ActionMode的上下文菜单,并让该ListView中的列表项支持复现,实现批量操作。

最后,就是当用户选择了一定数量的选项后,点击菜单中的Item进行某项批量操作后,执行对应的操作,并刷新ListView。


理清了我们想要实现的大致效果,接着我们要做的

就是整理一下思路,然后逐步的去编写代码,完成实现工作。let's do it !


首先,我们已经知道了自己 想要以一个联系人列表作为场景。

那么,自然我们会需要一个ListView来绑定和存放这些联系人数据。

于是,我们先将存放ListView以及定义该ListView的Item的细节的布局文件搞出来,分别为:


context_menu_action_mode.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:orientation="vertical" >

    <ListView
        android:id="@+id/context_menu_listView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>

context_menu_action_mode_item.xml
<?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:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin" >

    <ImageView
        android:id="@+id/user_head"
        android:layout_width="55dp"
        android:layout_height="55dp"
        android:contentDescription="@string/user_head_description"
        android:src="@drawable/headimage_default" />

    <TextView
        android:id="@+id/user_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="20dp"
        android:layout_marginStart="20dp"
        android:layout_toEndOf="@id/user_head"
        android:layout_toRightOf="@id/user_head"
        android:textSize="25sp" />

    <TextView
        android:id="@+id/phone_number"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBottom="@id/user_head"
        android:layout_marginLeft="20dp"
        android:layout_marginStart="20dp"
        android:layout_toEndOf="@id/user_head"
        android:layout_toRightOf="@id/user_head" />

    <CheckBox
        android:id="@+id/contact_selected_checkbox"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentEnd="true"
        android:layout_alignParentRight="true"
        android:layout_centerVertical="true"
        android:clickable="false"
        android:focusable="false" />

</RelativeLayout>

关于布局的定义,并没有什么难点。

唯一需要注意的是,我们为了更加友好的交互体验,所以在用户长按ListView进入可复选的模式后,

在每个列表的最右侧添加显示了一个CheckBox,以提示用户是否成功选择到了想要操作的列表项。

CheckBox只有在用户进入复选模式后,才显示,所以我们需要在后面注意在代码中动态的控制其显示情况。

并且!更需要注意的是,记得将CheckBox的clickable与focusable两个属性的值设置为false!

这样做的原因是因为CheckBox(定义在作为ListView的Item文件当中)自身的响应焦点及点击事件的优先级高于ListView自身。

所以,如果忘记设置的话,焦点及响应事件将被拦截在CheckBox,无法到达ListView。


第二步,当我们定义好了ListView的相关程序之后,自然忘不了它的好基友:适配器Adapter

MyContactAdapter.java:

package com.example.android_menu_test_demo.adapter;

import java.util.ArrayList;
import com.example.android_menu_test_demo.R;
import com.example.android_menu_test_demo.domain.Contact;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.TextView;

public class MyContactAdapter extends BaseAdapter {

	private Context mContext;
	private ArrayList<Contact> contacts;
	private ViewHolder mViewHolder;
	private ArrayList<Contact> selected_contacts = new ArrayList<Contact>();

	private boolean itemMultiCheckable;

	public MyContactAdapter(Context mContext, ArrayList<Contact> contacts) {
		this.mContext = mContext;
		this.contacts = contacts;
	}

	@Override
	public int getCount() {
		return contacts.size();
	}

	@Override
	public Object getItem(int position) {
		return contacts.get(position);
	}

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

	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		if (convertView == null) {
			convertView = LayoutInflater.from(mContext).inflate(R.layout.contact_listview_item, null);

			mViewHolder = new ViewHolder();

			mViewHolder.user_head = (ImageView) convertView.findViewById(R.id.user_head);
			mViewHolder.user_name_text = (TextView) convertView.findViewById(R.id.user_name);
			mViewHolder.phone_number_text = (TextView) convertView.findViewById(R.id.phone_number);
			mViewHolder.item_seleted = (CheckBox) convertView.findViewById(R.id.contact_selected_checkbox);

			convertView.setTag(mViewHolder);
		} else {
			mViewHolder = (ViewHolder) convertView.getTag();
		}

		// ************对于控件的具体处理****************

		// 设置checkbox是否可见
		if (itemMultiCheckable) {
			mViewHolder.item_seleted.setVisibility(View.VISIBLE);
			// 如果checkbox可见,证明当前处于可多选操作情况下,则根据用户选择情况设置checkbox被选中状态
			if (selected_contacts.contains(contacts.get(position))) {
				mViewHolder.item_seleted.setChecked(true);
			} else {
				mViewHolder.item_seleted.setChecked(false);
			}

		} else {
			mViewHolder.item_seleted.setVisibility(View.GONE);
		}

		// 控件赋值
		Contact contact = contacts.get(position);
		mViewHolder.user_name_text.setText(contact.getUserName());
		mViewHolder.phone_number_text.setText(contact.getPhoneNumber());

		return convertView;
	}

	public void setItemMultiCheckable(boolean flag) {
		itemMultiCheckable = flag;
	}

	public void addSelectedContact(int position) {
		selected_contacts.add(contacts.get(position));
	}

	public void cancelSeletedContact(int position) {
		selected_contacts.remove(contacts.get(position));
	}

	public void clearSeletedContacts() {
		selected_contacts = new ArrayList<Contact>();
	}

	public void deleteSeletedContacts() {
		for (Contact contact : selected_contacts) {
			contacts.remove(contact);
		}
	}

	static class ViewHolder {
		ImageView user_head;
		TextView user_name_text, phone_number_text;
		CheckBox item_seleted;
	}
}

适配器类的定义与我们开发中最常见的定义并没有太多区别。

值得注意的的代码,无非就是前面谈到的,做好动态控制CheckBox显示状态的工作。

另外,我们在适配器的定义中,为了让listview要显示的数据,更便于装载和传递,

通常会定义封装数据的实体类,正如上面的Contact类,不过这个太简单,就没贴代码的必要了。


接下来,就是我们想要实现的功能的重点了,

我们说到希望通过ListView的长点击事件,来触发一个上下文菜单来进行事件处理。

在Android 3.0之后添加的ActionMode相对于之前的普通上下文菜单,

显然更适合对于批量事件的处理,有着更好的交互体验。


所以说,既然将要使用到上下文 菜单,那么,废话少说。

先定义一个我们需要的简单的菜单文件:

multi_acitonmode_menu.xml:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >

    <item
        android:id="@+id/menu_cancle"
        android:showAsAction="always"
        android:title="@string/item_cancle"/>
    
        <item
        android:id="@+id/menu_delete"
        android:showAsAction="always"
        android:title="@string/item_delete"/>

</menu>

紧接着,一切准备 工作我们都已经基本就绪,

那么接下来要做的,自然就是Activity的代码编写工作了。

ContextMenuActionModeActivity.java

package com.example.android_menu_test_demo;

import android.view.ActionMode;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.AbsListView.MultiChoiceModeListener;
import java.util.ArrayList;

import com.example.android_menu_test_demo.adapter.MyContactAdapter;
import com.example.android_menu_test_demo.domain.Contact;

import android.annotation.TargetApi;
import android.app.Activity;
import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;

@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public class ContextMenuActionModeActivity extends Activity {

	private ListView contact_list_view;
	private ProgressDialog mDialog;

	private MyContactAdapter mAdpater;
	private MultiModeCallback mCallback;

	// 模拟数据
	private ArrayList<Contact> contacts;
	private String[] userNames = new String[] { "Jack", "Rose", "Matt", "Adam", "Xtina", "Blake", "Tupac", "Biggie",
			"T.I", "Eminem" };
	private String[] phoneNumbers = new String[] { "138-0000-0001", "138-0000-0002", "138-0000-0003", "138-0000-0004",
			"138-0000-0005", "138-0000-0006", "138-0000-0007", "138-0000-0008", "138-0000-0009", "138-0000-0010" };

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

		new ContactsDownloadTask().execute();

	}

	private void initView() {
		contact_list_view = (ListView) this.findViewById(R.id.context_menu_listView);

		mDialog = new ProgressDialog(this);

		mDialog.setTitle("提示信息");
		mDialog.setMessage("下载联系人列表中...");
		mDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);

		mCallback = new MultiModeCallback();
		contact_list_view.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
		contact_list_view.setMultiChoiceModeListener(mCallback);
	}

	private void downloadContactsFromServer() {
		if (contacts == null) {
			contacts = new ArrayList<Contact>();
		}

		for (int i = 0; i < userNames.length; i++) {
			contacts.add(new Contact(userNames[i], phoneNumbers[i]));
		}
	}

	private class ContactsDownloadTask extends AsyncTask<Void, Integer, Void> {

		private int currentlyProgressValue;

		@Override
		protected void onPreExecute() {
			mDialog.show();
			super.onPreExecute();
		}

		@Override
		protected Void doInBackground(Void... params) {

			while (currentlyProgressValue < 100) {
				publishProgress(++currentlyProgressValue);
				try {
					Thread.sleep(20);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}

			// download data from server
			downloadContactsFromServer();
			return null;
		}

		@Override
		protected void onProgressUpdate(Integer... values) {
			super.onProgressUpdate(values);
			mDialog.setProgress(values[0]);
		}

		@Override
		protected void onPostExecute(Void result) {
			super.onPostExecute(result);

			mAdpater = new MyContactAdapter(ContextMenuActionModeActivity.this, contacts);
			contact_list_view.setAdapter(mAdpater);

			mDialog.dismiss();
		}

	}

	private class MultiModeCallback implements MultiChoiceModeListener {
		private View mMultiSelectActionBarView;
		private TextView mSelectedCount;

		@Override
		public boolean onCreateActionMode(ActionMode mode, Menu menu) {
			mode.getMenuInflater().inflate(R.menu.multi_acitonmode_menu, menu);

			mAdpater.setItemMultiCheckable(true);
			mAdpater.notifyDataSetChanged();

			if (mMultiSelectActionBarView == null) {
				mMultiSelectActionBarView = LayoutInflater.from(ContextMenuActionModeActivity.this)
						.inflate(R.layout.list_multi_select_actionbar, null);
				mSelectedCount = (TextView) mMultiSelectActionBarView.findViewById(R.id.selected_conv_count);
			}
			mode.setCustomView(mMultiSelectActionBarView);
			((TextView) mMultiSelectActionBarView.findViewById(R.id.title)).setText(R.string.select_item);
			return true;
		}

		@Override
		public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
			// TODO Auto-generated method stub
			return false;
		}

		@Override
		public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
			switch (item.getItemId()) {
			case R.id.menu_cancle:
				mAdpater.setItemMultiCheckable(false);
				mAdpater.clearSeletedContacts();
				mAdpater.notifyDataSetChanged();
				mode.finish();
				break;
			case R.id.menu_delete:
				mAdpater.deleteSeletedContacts();
				mAdpater.notifyDataSetChanged();
				mode.invalidate();
				mode.finish();
				break;

			default:
				break;
			}
			return false;
		}

		@Override
		public void onDestroyActionMode(ActionMode mode) {
			mAdpater.setItemMultiCheckable(false);
			mAdpater.clearSeletedContacts();
			mAdpater.notifyDataSetChanged();

		}

		@Override
		public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked) {
			if (checked) {
				mAdpater.addSelectedContact(position);
			} else {
				mAdpater.cancelSeletedContact(position);
			}

			mAdpater.notifyDataSetChanged();

			updateSeletedCount();
			mode.invalidate();

		}

		public void updateSeletedCount() {
			mSelectedCount.setText(Integer.toString(contact_list_view.getCheckedItemCount()) + "条");
		}

	}

}

对于我们这样的菜鸟来说,上面activity代码中值得注意的可能是:

1、基本上,我们首先会定义一个异步任务类,模拟从网络下载数据的过程。有助于Adapter的API的使用的掌握。

2、我们在上面代码中定义的实现了MultiChoiceModeListener接口的内部类,MultiModeCallback就是帮助我们实现长按ListView(也试用于GridView),并且监听处理MultiChoice事件的关键。

     —  简单来说,可以看到,我们在该内部类的回调方法onCreateActionMode中,处理长按ListView后,ActionMode菜单相关的创建工作。并且在此控制ListView中的CheckBox显示,告知用户,我们已经进入到了可以进行批量操作的模式下。

     —  onActionItemClicked方法 用于监听和响应菜单上对应的选项的点击事件,你可以在此根据自己的需求,为对应的菜单选项编写响应代码。

     —  onDestroyActionMode方法 用于处理菜单销毁时,所要执行的动作。

     —  而onItemCheckedStateChanged方法 则就是用于监听处理ListView中每个列表项的选中状态改变时的回调了,我们会在这里根据需求完成对应的编码工作。

3、到了这里,我们对于我们想要的功能的实现,可以说已经是基本搞定了。但是,你可能已经在上面的MultiModeCallback类的某些代码中注意点到:

为了更加友善的交互感受,我们 还可以以ActionBar的形式,在菜单栏上,添加一段内容,正如 短信功能里所使用的那样,用以提示用户类似于“您当前已经选择了XX条内容”的信息。所以我们还会定义一个类似ActionBar的布局文件,如下:

list_multi_select_actionbar.xml:

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/custom_title_root"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal">

    <TextView
        android:id="@+id/title"
        android:layout_gravity="center_vertical"
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"
        android:textColor="#ffffff" />

    <TextView
        android:id="@+id/selected_conv_count"
        android:layout_gravity="center_vertical"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" 
        android:textColor="#ffffff"/>

</LinearLayout>

在上面的代码中,你可以看到,我们同样是在onCreateActionMode方法中完成ActionMode上下文菜单的装载工作的同时,也会进行对于该作为ActionBar使用的View的装载与显示控制工作。

在该View装载和显示工作完成之后,我们要做的就很简单了,只需要在onItemCheckedStateChanged中进行监听,当用户选中某个列表项时,对用于显示提示信息的TextView的显示内容进行更新,则OK了。


走到这一步,我们可以说是已经山寨完毕了,下一步要做的则可以将Demo编译到模拟器或者手机上,看看效果了~


Android ListView 长按弹出菜单详解 详细介绍文章在http://hi.baidu.com/dean_wang/blog/item/00b0e247d223b528cefca374.html上面。介绍了Android中的ListView的长按事件如何根据点击的项不一样弹出不同的菜单。这是整个工程源码。 立即下载

相关推荐

[kriging](一)网上下载的kriging克里金的C++程序的初步调试

笔者在网上下载了一份克里金的C++程序,水平有限,正在逐步地调试中。 初步 克里金法现在在许多软件都已经有集成了,据笔者所知: arcgis : 看过有的arcgis培训视频里面简略介绍了里面的插值方法,有克里金。 surfer :笔者用过这个,效果很好。 gocad :听说有 landmark &jason :研究生时候用的专业的石油物探软件,里面有克里金法,万恶的开始。 pykrig...

FOREST优快云 5610

Android ListView上下文菜单:ActionMode.CallBack

在这篇文章中,我们要分析上下文菜单 ( contextual action bar )。 这是与特定项目相关的菜单。 上下文菜单几乎可以应用于所有视图,但通常与ListView一起使用 。 我们谈论了很多列表视图,因为它是最重要的组件之一。 我们可以区分两种不同类型的上下文菜单: 浮动菜单 上下文动作模式(ActionMode) 浮动菜单用于低于3.0(API级别11)的An...

872

ZYNQ出现问题及解决办法汇总(一直更新)

问题目录使用软件及开发板版本一,vitis在build project时卡住。二,Could not find FPGA device on the board for connection 'Local'三,FPGA configuration failed:DONE PIN is not high四,Could not find ARM device on the board for connection 'Local' 使用软件及开发板版本 开发板:MZ7XA-7020 软件:vitis2020.2(

qq_45057368的博客 1万+

android listview上下文菜单,Android编程实现为ListView创建上下文菜单(ContextMenu)的方法...

本文实例讲述了Android编程实现为ListView创建上下文菜单(ContextMenu)的方法。分享给大家供大家参考,具体如下:ContextMenu称为上下文菜单,一般在控件上长按时弹出。今天我们学习ContextMenu的用法,这里与listview相结合,先在ListView显示几个Item,然后在Item上长按,弹出一个菜单(就是ContextMenu),点击菜单上的项目,提示刚才长...

weixin_33400830的博客 655

红队攻防渗透技术实战流程:云安全之云原生安全:特权模式和挂载模式

红队云攻防实战1. 什么是云 1. 什么是云

HACKONE的博客 572

知识图谱(Knowledge Graph)原理与代码实战案例讲解

知识图谱(Knowledge Graph)原理与代码实战案例讲解 作者:禅与计算机程序设计艺术 / Zen and the Art of Computer Programming 1. 背景介绍 1.1 问题的由来

AI天才研究院 1077

【Android】菜单功能的实现:上下文菜单

1.在主面板里面添加一个列表视图,如下: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" androi

Chunyang Guo 1277

MicroCap声学仿真介绍(六)-入耳式耳机仿真

从上图可以看出,后腔开了泄声孔后,振膜的最大位移从4.8um提升到了10um,振膜位移增加了一倍。在实际应用中,一般耳机的前腔和后腔都需要开泄声孔,开孔的大小和调音网布的阻尼需要根据客户的要求以及仿真的结果进行权衡选择。接着在主界面放置电阻、电感、电容,电阻值为Rms,电感值为Mms,电容值为Cms,如下图。假设后腔泄声孔的直径为1.2mm,宽度为0.3mm,对应调音网的阻抗为5.5e8欧姆。假设前腔泄声孔的直径为1.2mm,宽度为0.3mm,对应调音网的阻抗为5.5e8欧姆。

山无忧的博客 1800

android 联系人listview,获取系统联系人信息,并显示在ListView上

需求:把下列系统联系人的信息显示在一个ListView上,当点击listView子项时,把联系人的姓名和号码返回到前一个activity,并显示效果图代码实现所需权限:android.permission.READ_CONTACTS实体类Contact:package cn.contactinfo;public class Contact{private String name;private S...

weixin_31354669的博客 1506

金蝶Apusic应用服务器 未授权目录遍历漏洞复现

由于金蝶Apusic应用服务器/admin/protected/selector/server_file/files、/admin/protected/selector/server_file/folders 等接口没有进行校验和过滤,直接将参数拼接到文件操作中,导致出现目录遍历漏洞,未经身份验证的远程攻击者可通过此漏洞读取系统内部系统文件路径及信息,导致信息泄露,系统处于极不安全状态。

0xSec 2165

Authentication Assertion Tickets,SAP 系统到系统单点登录里的短命凭证

SAP 系统间的身份传递机制存在 Authentication Assertion Ticket 和 SAP Logon Ticket 两种易混淆的凭证。前者用于系统间短时身份委托(有效期2分钟,通过HTTP头传输),后者用于浏览器SSO(可配置有效期,通过Cookie传输)。Assertion Ticket依赖签发系统的数字签名和严格的时间同步,适用于ABAP/Java系统间的后台作业调用。现代SAP架构已转向OAuth 2.0等标准协议,但老系统中仍需注意两种票据的关键差异:传输方式、有效期、接收方限制

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 602

android菜单详解三:上下文菜单

创建一个上下文菜单 一个上下文菜单跟PC上的右键菜单类似.你应使用上下文菜单为用户界面上的某个部分提供动作选择功能.在Android中,一个上下文菜单会在用户长按一个界面条目时出现. 你可以为任何View创建上下文菜单,但是在 ListView中是最常用到上下文菜单的.每当用户在一个ListView项上长按,并且这个ListView注册了上下文菜单,那么被按的 list item就会弹出上

nkmnkm的专栏 5380

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

Android——ListView使用ActionMode实现的上下文长按多选菜单

操作环境:Android Studio 以及自带的模拟器,相关配置如下 话不多说,先上结果截图。 第一张是初始应用的菜单界面。第二张是长按选中之后的操作界面。由图中可以看出,长按之后,选中项会标绿(ps:原谅我这渣渣的审美),并且上面标题菜单栏会显示选中了几项,出现三个选项,分别是返回,选中和删除。这个菜单是可以定制的,我这边三个选项都设置成了返回,毕竟只是为了实现这个长按多选菜单(请允许我...

小白 1258

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

listview上下文菜单_Android ListView上下文菜单:ActionMode.CallBack

listview上下文菜单 在这篇文章中,我们要分析上下文菜单 ( contextual action bar )。 这是与特定项目相关的菜单。 上下文菜单几乎可以应用于所有视图,但通常与ListView一起使用 。 我们谈论了很多列表视图,因为它是最重要的组件之一。 我们可以区分两种不同类型的上下文菜单: 浮动菜单 上下文动作模式(ActionMode) 浮动菜单用于低于3....

602

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

Android——ListView使用ActionMode实现的上下文长按多选菜单(2)

开发是面向对象。我们找工作应该更多是面向面试。哪怕进大厂真的只是去宁螺丝,但你要进去得先学会面试的时候造飞机不是么?作者13年java转Android开发,在小厂待过,也去过华为,OPPO等,去年四月份进了阿里一直到现在。等大厂待过也面试过很多人。深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长,不成体系的学习效果低效漫长且无助。这里附上上述的技术体系图相关的几十套腾讯、头条、阿里、美团等公司的面试题,把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含。

2401_84545016的博客 588

Android——ListView使用ActionMode实现的上下文长按多选菜单(1)

分享一份工作1到5年以上的Android程序员架构进阶学习路线体系,希望能对那些还在从事Android开发却还不知道如何去提升自己的,还处于迷茫的朋友!阿里P7级Android架构师技术脑图;查漏补缺,体系化深入学习提升**全套体系化高级架构视频;**七大主流技术模块,视频+源码+笔记有任何问题,欢迎广大网友一起来交流《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》点击传送门,即可获取!//定义item并且加入list中i < 6;i++){

2401_84009529的博客 839
上一篇: Android - SurfaceView + MediaPlayer实现分段视频无缝播放
下一篇: Android - Acitivty生命周期 理解
LaterEqualsNever
博客等级 码龄12年 297粉丝 61原创
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值