通讯录小案例
来源:互联网 发布:巴黎住宿攻略 知乎 编辑:程序博客网 时间:2024/06/06 07:51
一、图片效果图
(1).点击添加按钮,跳转到第二个页面,输入姓名、性别、号码,点击提交,添加到第一个页面中。
(2).在第一个页面中,选择其中一个item向左滑动,显示删除,点击删除,删除当前信息。
(3).在第一个页面中,选择其中一个item点击,则携带数据跳转到第二个页面中,修改后提交,更改第一个页面信息。
(4).在一个页面中,点击发信息,则携带电话号码进入发信息界面,点击打电话,则携带电话号码进入打电话界面
二、布局
activity_main布局
<?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:background="#8B8B83"> <LinearLayout android:id="@+id/ll_title" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/colorPrimaryDark" android:padding="10dp"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="好友" android:textSize="20sp" /> <TextView android:layout_width="wrap_content" android:layout_height="0dp" android:layout_weight="1" /> <TextView android:id="@+id/tv_add" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="添加" android:textSize="20sp" /> </LinearLayout> <ListView android:id="@+id/lv_main" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_below="@id/ll_title"></ListView></RelativeLayout>
activity_add布局
<?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="#8B8B83" android:orientation="vertical"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/colorPrimaryDark" android:gravity="center_vertical" android:padding="10dp"> <TextView android:id="@+id/cancel" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="返回" android:textSize="24sp" /> <TextView android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" /> <TextView android:id="@+id/confirm" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="提交" android:textSize="24sp" /> </LinearLayout> <ImageView android:id="@+id/iv_touxiang" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:layout_marginBottom="10dp" android:layout_marginTop="20dp" android:src="@mipmap/touxiang" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="5dp"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="姓名: " /> <EditText android:id="@+id/et_name" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center_vertical" android:padding="5dp"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="性别: " /> <RadioGroup android:id="@+id/rg_gender" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:padding="10dp"> <RadioButton android:id="@+id/rb_man" android:layout_width="wrap_content" android:layout_height="wrap_content" android:checked="true" android:text="男" /> <RadioButton android:id="@+id/rb_wom" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="女" /> </RadioGroup> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="5dp"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="号码: " /> <EditText android:id="@+id/et_number" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" /> </LinearLayout></LinearLayout>
item_main布局
<?xml version="1.0" encoding="utf-8"?><com.atguigu.listviewadapter.util.SlideLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="70dp"> <include android:id="@+id/item_content" layout="@layout/item_adapter" /> <include android:id="@+id/item_delete" layout="@layout/item_delete" /></com.atguigu.listviewadapter.util.SlideLayout>
item_adapter布局
<?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="70dp" android:layout_centerVertical="true" android:orientation="horizontal" android:gravity="center_vertical" android:padding="5dp"> <ImageView android:id="@+id/item_touxiang" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="5dp" android:layout_marginRight="10dp" android:src="@mipmap/touxiang" /> <LinearLayout android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:layout_gravity="center_vertical" android:gravity="center_vertical" android:orientation="vertical"> <TextView android:id="@+id/item_name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center" android:text="name" /> <TextView android:id="@+id/item_gender" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center" android:text="gender" /> <TextView android:id="@+id/item_number" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center" android:text="number" /> </LinearLayout> <Button android:id="@+id/send" android:layout_width="wrap_content" android:layout_height="wrap_content" android:focusable="false" android:text="发信息" /> <Button android:id="@+id/call" android:layout_width="wrap_content" android:layout_height="wrap_content" android:focusable="false" android:text="打电话" /></LinearLayout>
item_delete布局
<?xml version="1.0" encoding="utf-8"?><TextView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="60dp" android:background="#ff0000" android:gravity="center" android:text="删除" android:textSize="25sp" android:padding="5dp" android:textColor="#ffffff"/>
三、代码
自定义控件代码
package com.atguigu.listviewadapter.util;import android.content.Context;import android.util.AttributeSet;import android.view.MotionEvent;import android.view.View;import android.widget.FrameLayout;import android.widget.Scroller;/** * 自定义控件,侧滑菜单item */public class SlideLayout extends FrameLayout { private View contentView; private View deleteView; /** * 滚动器 */ private Scroller scroller; /** * ContentView的宽 */ private int contentWidth; private int deleteWidth; private int viewHeight; //他们的高都是相同的 public SlideLayout(Context context, AttributeSet attrs) { super(context, attrs); scroller = new Scroller(context); } /** * 当布局文件加载完成的时候回调这个方法 */ @Override protected void onFinishInflate() { super.onFinishInflate(); contentView = getChildAt(0); deleteView = getChildAt(1); } /** * 在测量方法里,得到各个控件的宽和高 * * @param widthMeasureSpec * @param heightMeasureSpec */ @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); contentWidth = contentView.getMeasuredWidth(); deleteWidth = deleteView.getMeasuredWidth(); viewHeight = getMeasuredHeight(); } @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); //指定菜单的位置 deleteView.layout(contentWidth, 0, contentWidth + deleteWidth, viewHeight); } private float startX; private float startY; private float downX;//只赋值一次 private float downY; /** * 解决滑动item后不能自动打开或者关闭 * @param event * @return */ @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: //1.按下记录坐标 downX = startX = event.getX(); downY = startY = event.getY(); break; case MotionEvent.ACTION_MOVE: //2.记录结束值 float endX = event.getX(); float endY = event.getY(); //3.计算偏移量 float distanceX = endX - startX; int toScrollX = (int) (getScrollX() - distanceX); //屏蔽非法值 if (toScrollX < 0) { toScrollX = 0; } else if (toScrollX > deleteWidth) { toScrollX = deleteWidth; } scrollTo(toScrollX, getScrollY()); startX = event.getX(); startY = event.getY(); //在X轴和Y轴滑动的距离 float DX = Math.abs(endX - downX); float DY = Math.abs(endY - downY); //解决item滑动后不能自动打开和关闭 if (DX > DY && DX > 8) { //水平方向滑动 //响应侧滑 //反拦截,事件给SlideLayout getParent().requestDisallowInterceptTouchEvent(true); } break; case MotionEvent.ACTION_UP: int totalScrollX = getScrollX();//偏移量 if (totalScrollX < deleteWidth / 2) { //关闭delete按钮 closeDelete(); } else { //打开delete按钮 openDelete(); } break; } return true; } /** * true:拦截孩子的事件,但会执行当前控件的onTouchEvent()方法 * false:不拦截孩子的事件,事件继续传递 * * @param event * @return */ @Override public boolean onInterceptTouchEvent(MotionEvent event) { boolean intercept = false; switch (event.getAction()) { case MotionEvent.ACTION_DOWN: //1.按下记录坐标 downX = startX = event.getX(); downY = startY = event.getY(); if(onStateChangeListenter != null){ onStateChangeListenter.onDown(this); } break; case MotionEvent.ACTION_MOVE: //2.记录结束值 float endX = event.getX(); //3.计算偏移量 startX = event.getX(); //在X轴和Y轴滑动的距离 float DX = Math.abs(endX - downX); //解决item滑动后不能自动打开和关闭 if (DX > 8) { intercept = true; } break; case MotionEvent.ACTION_UP: break; } return intercept; } /** * 关闭delete按钮 */ public void closeDelete() { //目标位置 --> 0 int distanceX = 0 - getScrollX(); scroller.startScroll(getScrollX(), getScrollY(), distanceX, getScrollY()); invalidate();//强制刷新 if(onStateChangeListenter != null){ onStateChangeListenter.onClose(this); } } /** * 打开delete按钮 */ public void openDelete() { //目标位置 --> deleteWidth int distanceX = deleteWidth - getScrollX(); scroller.startScroll(getScrollX(), getScrollY(), distanceX, getScrollY()); invalidate();//强制刷新 if(onStateChangeListenter != null){ onStateChangeListenter.onOpen(this); } } /** * 调用invalidate()时自动调用此方法 */ @Override public void computeScroll() { super.computeScroll(); if (scroller.computeScrollOffset()) { scrollTo(scroller.getCurrX(), scroller.getCurrY()); invalidate(); } } /** * 监听SlideLayout状态的改变 * 限制只能打开一个item */ public interface OnStateChangeListenter{ void onClose(SlideLayout layout); void onDown(SlideLayout layout); void onOpen(SlideLayout layout); } private OnStateChangeListenter onStateChangeListenter; public void setOnStateChangeListenter(OnStateChangeListenter onStateChangeListenter){ this.onStateChangeListenter = onStateChangeListenter; }}
数据库帮助类代码
package com.atguigu.listviewadapter.db;import android.content.Context;import android.database.sqlite.SQLiteDatabase;import android.database.sqlite.SQLiteOpenHelper;/** * Created by YY on 2017/7/6. */public class PersonOpenHelper extends SQLiteOpenHelper { /** * Person建表语句 */ public static final String CREATE_PERSON = "create table Person(id integer primary key autoincrement,personId integer,name text,gender text,number text)"; public PersonOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) { super(context, name, factory, version); } @Override public void onCreate(SQLiteDatabase db) { db.execSQL(CREATE_PERSON);//创建Person表 } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { }}
数据库操作类代码
package com.atguigu.listviewadapter.model;import android.content.ContentValues;import android.content.Context;import android.database.Cursor;import android.database.sqlite.SQLiteDatabase;import com.atguigu.listviewadapter.Person;import com.atguigu.listviewadapter.db.PersonOpenHelper;import java.util.ArrayList;import java.util.List;/** * Created by YY on 2017/7/6. */public class PersonDB { /** * 数据库名 */ public static final String DB_NAME = "listview_adapter"; /** * 数据库版本 */ public static final int VERSION = 1; private static PersonDB personDB; private SQLiteDatabase db; /** * 将构造方法私有化 */ private PersonDB(Context context) { PersonOpenHelper dbHelper = new PersonOpenHelper(context, DB_NAME, null, VERSION); db = dbHelper.getWritableDatabase(); } /** * 获取PersonDB的实例 */ public synchronized static PersonDB getInstance(Context context) { if (personDB == null) { personDB = new PersonDB(context); } return personDB; } public void savePerson(Person person) { if (person != null) { ContentValues values = new ContentValues(); values.put("name", person.getName()); values.put("gender", person.getGender()); values.put("number", person.getNamber()); db.insert("Person", null, values); } } /** * 从数据库中读取人的信息 */ public List<Person> showPerson() { List<Person> list = new ArrayList<Person>(); Cursor cursor = db.query("Person", null, null, null, null, null, null); if (cursor.moveToFirst()) { do { Person person = new Person(); person.setPersonId(cursor.getInt(cursor.getColumnIndex("id"))); person.setName(cursor.getString(cursor.getColumnIndex("name"))); person.setGender(cursor.getString(cursor.getColumnIndex("gender"))); person.setNamber(cursor.getString(cursor.getColumnIndex("number"))); list.add(person); } while (cursor.moveToNext()); } if (cursor != null) { cursor.close(); } return list; } /** * 从数据库中删除人的信息 */ public void deletePerson(int personId) { db.delete("Person", "id=?", new String[]{personId + ""}); } /** * 从数据库中更新人的信息 */ public void updatePerson(Person person) { ContentValues contentValues = new ContentValues(); contentValues.put("name", person.getName()); contentValues.put("gender", person.getGender()); contentValues.put("number", person.getNamber()); db.update("Person", contentValues, "id=?", new String[]{person.getPersonId() + ""}); }}
Person类代码
package com.atguigu.listviewadapter;import android.graphics.drawable.Drawable;import java.io.Serializable;/** * Created by YY on 2017/7/6. */public class Person implements Serializable { private int personId; private String name; private String gender; private String namber; public Person() { } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getGender() { return gender; } public void setGender(String gender) { this.gender = gender; } public String getNamber() { return namber; } public void setNamber(String namber) { this.namber = namber; } public Person(int personId, String name, String gender, String namber) { this.name = name; this.gender = gender; this.namber = namber; } public int getPersonId() { return personId; } public void setPersonId(int personId) { this.personId = personId; } @Override public String toString() { return "Person{" + "personId=" + personId + ", name='" + name + '\'' + ", gender='" + gender + '\'' + ", namber='" + namber + '\'' + '}'; }}
MainActivity类代码
package com.atguigu.listviewadapter;import android.app.Activity;import android.content.Intent;import android.database.Cursor;import android.database.sqlite.SQLiteDatabase;import android.net.Uri;import android.os.Bundle;import android.util.Log;import android.view.View;import android.view.ViewGroup;import android.view.Window;import android.widget.BaseAdapter;import android.widget.Button;import android.widget.ImageView;import android.widget.LinearLayout;import android.widget.ListView;import android.widget.TextView;import com.atguigu.listviewadapter.model.PersonDB;import com.atguigu.listviewadapter.util.SlideLayout;import java.util.List;public class MainActivity extends Activity { private TextView tv_add; private ListView lv_main; private MyAdapter myAdapter; private List<Person> list; private int requestCode = 2; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.activity_main); tv_add = (TextView) findViewById(R.id.tv_add); lv_main = (ListView) findViewById(R.id.lv_main); tv_add.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(MainActivity.this, AddActivity.class); startActivityForResult(intent, requestCode); } }); //添加数据 PersonDB personDB = PersonDB.getInstance(this); list = personDB.showPerson(); //设置BaseAdapter myAdapter = new MyAdapter(); //添加到lv_main中 lv_main.setAdapter(myAdapter); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == 2) { if (resultCode == 3) { // 从data中取出数据 Person person = (Person) data.getSerializableExtra("person_data"); list.add(person); } } if (requestCode == 5) { if (resultCode == 4) { Log.e("onActivityResult", "onActivityResult"); list.clear(); PersonDB personDB = PersonDB.getInstance(this); list = personDB.showPerson(); } } myAdapter.notifyDataSetChanged(); } public class MyAdapter extends BaseAdapter { @Override public int getCount() { return list.size(); } @Override public Object getItem(int position) { return null; } @Override public long getItemId(int position) { return 0; } @Override public View getView(final int position, View convertView, ViewGroup parent) { ViewHolder viewHolder; if (convertView == null) { convertView = View.inflate(MainActivity.this, R.layout.item_main, null); viewHolder = new ViewHolder(); //得到当前行的数据对象 viewHolder.item_delete = (TextView) convertView.findViewById(R.id.item_delete); viewHolder.item_content = (LinearLayout) convertView.findViewById(R.id.item_content); viewHolder.imageView = (ImageView) viewHolder.item_content.findViewById(R.id.item_touxiang); viewHolder.nameTV = (TextView) viewHolder.item_content.findViewById(R.id.item_name); viewHolder.genderTV = (TextView) viewHolder.item_content.findViewById(R.id.item_gender); viewHolder.numberTV = (TextView) viewHolder.item_content.findViewById(R.id.item_number); viewHolder.send = (Button) viewHolder.item_content.findViewById(R.id.send); viewHolder.call = (Button) viewHolder.item_content.findViewById(R.id.call); convertView.setTag(viewHolder); } else { viewHolder = (ViewHolder) convertView.getTag(); } final Person person = list.get(position); //设置数据 viewHolder.nameTV.setText(person.getName()); viewHolder.genderTV.setText(person.getGender()); viewHolder.numberTV.setText(person.getNamber()); final String number = list.get(position).getNamber(); /** * 点击发信息,携带电话号码进入发信息界面 */ viewHolder.send.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { String actionSend = Intent.ACTION_SENDTO; Intent intentSend = new Intent(actionSend); intentSend.setData(Uri.parse("smsto:" + number)); startActivity(intentSend); } }); /** * 点击打电话,携带电话号码进入打电话界面 */ viewHolder.call.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { String actionCall = Intent.ACTION_DIAL; Intent intentCall = new Intent(actionCall); intentCall.setData(Uri.parse("tel:" + number)); startActivity(intentCall); } }); /** * 给每一个item_content设置监听,跳转到AddActivity界面,用于更新数据 */ viewHolder.item_content.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Person person = list.get(position); Intent intent = new Intent(MainActivity.this, AddActivity.class); intent.putExtra("onClick_item", true); intent.putExtra("person", person); int requestCode2 = 5; startActivityForResult(intent, requestCode2); } }); /** * 点击删除按钮,删除数据库中的数据和删除列表中的数据,并更新列表 */ viewHolder.item_delete.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Person personDelete = list.get(position); PersonDB personDB = PersonDB.getInstance(MainActivity.this); personDB.deletePerson(personDelete.getPersonId()); list.remove(position); SlideLayout slideLayout = (SlideLayout) v.getParent(); slideLayout.closeDelete(); myAdapter.notifyDataSetChanged(); } }); SlideLayout slideLayout = (SlideLayout) convertView; slideLayout.setOnStateChangeListenter(new MyOnStateChangeListenter()); return convertView; } } private SlideLayout slideLayout; class MyOnStateChangeListenter implements SlideLayout.OnStateChangeListenter { @Override public void onClose(SlideLayout layout) { if (slideLayout == layout) { slideLayout = null; } } @Override public void onDown(SlideLayout layout) { if (slideLayout != null && slideLayout != layout) { slideLayout.closeDelete(); } } @Override public void onOpen(SlideLayout layout) { slideLayout = layout; } } private static class ViewHolder { TextView item_delete; LinearLayout item_content; ImageView imageView; TextView nameTV; TextView genderTV; TextView numberTV; Button send; Button call; }}
AddActivity代码
package com.atguigu.listviewadapter;import android.app.Activity;import android.content.Intent;import android.os.Bundle;import android.util.Log;import android.view.View;import android.view.Window;import android.widget.EditText;import android.widget.ImageView;import android.widget.RadioButton;import android.widget.RadioGroup;import android.widget.TextView;import com.atguigu.listviewadapter.model.PersonDB;public class AddActivity extends Activity implements View.OnClickListener { private TextView cancel; private TextView confirm; private ImageView iv_touxiang; private EditText et_name; private RadioGroup rg_gender; private EditText et_number; private String gender = "男"; /** * 是否是点击onItemClick跳转过来的 */ private boolean isFromItem; /** * 记录更新的person */ private Person itemPerson; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.activity_add); cancel = (TextView) findViewById(R.id.cancel); confirm = (TextView) findViewById(R.id.confirm); iv_touxiang = (ImageView) findViewById(R.id.iv_touxiang); et_name = (EditText) findViewById(R.id.et_name); rg_gender = (RadioGroup) findViewById(R.id.rg_gender); et_number = (EditText) findViewById(R.id.et_number); //如果是从Item中跳转过来,设置数据 isFromItem = getIntent().getBooleanExtra("onClick_item", false); itemPerson = (Person) getIntent().getSerializableExtra("person"); if (isFromItem) { et_name.setText(itemPerson.getName()); String gender_item = itemPerson.getGender(); if (gender_item.equals(gender)) { rg_gender.check(R.id.rb_man); } else { rg_gender.check(R.id.rb_wom); } et_number.setText(itemPerson.getNamber()); } rg_gender.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() { @Override public void onCheckedChanged(RadioGroup group, int checkedId) { RadioButton checked = (RadioButton) findViewById(checkedId); gender = checked.getText().toString(); } }); cancel.setOnClickListener(this); confirm.setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.cancel: finish(); break; case R.id.confirm: String name = et_name.getText().toString(); String number = et_number.getText().toString(); if (!isFromItem) { Person person = new Person(); person.setName(name); person.setGender(gender); person.setNamber(number); PersonDB personDB = PersonDB.getInstance(this); personDB.savePerson(person); Intent intent = new Intent(); intent.putExtra("person_data", person); int resultCode = 3; setResult(resultCode, intent); } else { PersonDB personDB = PersonDB.getInstance(this); itemPerson.setName(name); itemPerson.setGender(gender); itemPerson.setNamber(number); personDB.updatePerson(itemPerson); Intent intent = new Intent(); int resultCode = 4; setResult(resultCode, intent); } finish(); break; } }}
阅读全文
0 0
- 通讯录小案例
- 10.android通讯录案例
- 59-通讯录案例
- 通讯录小项目
- Python通讯录小程序
- 通讯录小项目
- 小程序-通讯录
- 小案例
- asp.net案例分析-“通讯录”-1-Vs2008调试“通讯录”
- 通讯录联系人,带右边索引案例
- 仿通讯录ListView小例子
- 通讯录小软件的制作
- IOS 开发小作品 通讯录
- 通讯录小感想(1)
- 小程序实现通讯录查询
- 通讯录--C语言小项目
- css小案例 小demo
- SQL Server小案例
- 自定义饼状图控件PieView
- swift3.0 入门学习笔记之二 闭包
- 执行django-admin.py startproject test后,无法创建项目的解决办法
- 使用IntellJ idea以maven作为项目构建的方式创建java工程
- 认识JSON
- 通讯录小案例
- Java发送get,post请求
- QT QML自定义等待提示框
- Jmeter运行报警告信息
- Linux 安装 Eclipse
- lambda函数
- 从mysql中将数据表复制给hbase
- OSG学习:计算纹理坐标
- 算法2:树的带权路径长度(创新工场)