Android项目实战系列—基于博学谷(五)个人资料

news/2024/7/5 20:46:27

image

由于这个模块内容较多,篇幅较长,请耐心阅读。


个人资料模块分为两个部分

  • 个人资料
  • 资料修改

一、个人资料

1、个人资料界面

(1)、创建个人资料界面

com.buxuegu.activity包中创建一个java类,命名为UserInfoActivity。在res/layout文件夹下创建一个布局文件,命名为activity_user_info

(2)、界面代码——activity_user_info.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:color/white">
    <include layout="@layout/main_title_bar"/>
    <RelativeLayout
        android:id="@+id/rl_head"
        android:layout_width="fill_parent"
        android:layout_height="60dp"
        android:layout_marginLeft="15dp"
        android:layout_marginRight="15dp">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:text="头像"
            android:textColor="#000000"
            android:textSize="16sp" />
        <ImageView
            android:id="@+id/iv_head_icon"
            android:layout_width="40dp"
            android:layout_height="40dp"
            android:layout_alignParentRight="true"
            android:layout_centerVertical="true"
            android:src="@drawable/default_icon"/>
    </RelativeLayout>
    <View
        android:layout_width="fill_parent"
        android:layout_height="1dp"
        android:background="#E4E4E4"/>
    <RelativeLayout
        android:id="@+id/rl_account"
        android:layout_width="fill_parent"
        android:layout_height="60dp"
        android:layout_marginLeft="15dp"
        android:layout_marginRight="15dp">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:text="用户名"
            android:textColor="#000000"
            android:textSize="16sp"/>
        <TextView
            android:id="@+id/tv_user_name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_centerVertical="true"
            android:layout_marginRight="5dp"
            android:text="account"
            android:textColor="#a3a3a3"
            android:textSize="14sp"/>
    </RelativeLayout>
    <View
        android:layout_width="fill_parent"
        android:layout_height="1dp"
        android:background="#E4E4E4"/>
    <RelativeLayout
        android:id="@+id/rl_nickName"
        android:layout_width="fill_parent"
        android:layout_height="60dp"
        android:layout_marginLeft="15dp"
        android:layout_marginRight="15dp">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:text="昵称"
            android:textColor="#000000"
            android:textSize="16sp"/>
        <TextView
            android:id="@+id/tv_nickName"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_centerVertical="true"
            android:layout_marginRight="5dp"
            android:singleLine="true"
            android:text="昵称"
            android:textColor="#a3a3a3"
            android:textSize="14sp"/>
    </RelativeLayout>
    <View
        android:layout_width="fill_parent"
        android:layout_height="1dp"
        android:background="#E4E4E4"/>
    <RelativeLayout
        android:id="@+id/rl_sex"
        android:layout_width="fill_parent"
        android:layout_height="60dp"
        android:layout_marginLeft="15dp"
        android:layout_marginRight="15dp">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:text="性别"
            android:textColor="#000000"
            android:textSize="16sp"/>
        <TextView
            android:id="@+id/tv_sex"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_centerVertical="true"
            android:layout_marginRight="5dp"
            android:text=""
            android:textColor="#a3a3a3"
            android:textSize="14sp"/>
    </RelativeLayout>
    <View
        android:layout_width="fill_parent"
        android:layout_height="1dp"
        android:background="#E4E4E4"/>
    <RelativeLayout
        android:id="@+id/rl_signature"
        android:layout_width="fill_parent"
        android:layout_height="60dp"
        android:layout_marginLeft="15dp"
        android:layout_marginRight="15dp">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:singleLine="true"
            android:text="签名"
            android:textColor="#000000"
            android:textSize="16sp"/>
        <TextView
            android:id="@+id/tv_signature"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_centerVertical="true"
            android:layout_marginRight="5dp"
            android:textColor="#a3a3a3"
            android:textSize="14sp"/>
    </RelativeLayout>
    <View
        android:layout_width="fill_parent"
        android:layout_height="1dp"
        android:background="#E4E4E4"/>
</LinearLayout>

2、创建UserBean

选中com.boxuegu包,新建一个bean包。在bean包中创建一个Java类,命名为UserBean。代码如下
package com.boxuegu.bean;

public class UserBean {
    public String userName;  //用户名
    public String nickName;  //昵称
    public String sex;       //性别
    public String signature; //签名
}

3、创建用户信息表

选中com.boxuegu包,新建一个sqlite包。在sqlite包中创建一个Java类,命名为QLiteHelper。因为SQLiteHelper类继承SQLiteOpenHelper类,需要修改主类。代码如下
package com.boxuegu.sqlite;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

//SQLiteHelper类继承自SQLiteOpenHelper类
public class SQLiteHelper extends SQLiteOpenHelper {

    public static final int DB_VERSION = 1;  //数据库的版本
    public static final String DB_NAME = "wordpress.db";   //数据库的名称
    public static final String U_USERINFO = "userinfo";   //个人资料
    public SQLiteHelper(Context context){
        super(context,DB_NAME,null,DB_VERSION);
    }
    
    //创建数据库
    @Override
    public void onCreate(SQLiteDatabase db){
        //创建用户信息表
        db.execSQL("CREATE TABLE IF NOT EXISTS " + U_USERINFO + "( " +
                "_id INTEGER PRIMARY KEY AUTOINCREMENT, "
                + "userName VARCHAR,"  //用户名
                + "nickName VARCHAR,"  //昵称
                + "sex VARCHAR,"       //性别
                + "signature VARCHAR"  //签名
                + ")" );
    }

    //数据库升级 版本号增加 升级调用此方法
    @Override
    public void onUpgrade(SQLiteDatabase db,int oldVersion,int newVersion){
        db.execSQL("DROP TABLE IF NOT EXISTS " + U_USERINFO);
        onCreate(db);

    }
}

4、创建DBUtils工具类

选中com.boxuegu.utils包,创建一个Java类,命名为BUtilsr。用于操作数据库。代码如下
package com.boxuegu.utils;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import com.boxuegu.bean.UserBean;
import com.boxuegu.sqlite.SQLiteHelper;

public class DBUtils {
    private static SQLiteHelper helper;
    private static SQLiteDatabase db;
    private static DBUtils instance = null;
    public DBUtils(Context context) {
        helper = new SQLiteHelper(context);
        //getWritableDatabase();可写的数据库对象
        db = helper.getWritableDatabase();
    }

    public static DBUtils getInstance(Context context) {
        if (instance == null) {
            instance = new DBUtils(context);
        }
        return instance;
    }

    //保存用户个人资料信息
    public void saveUserInfo(UserBean bean) {
        ContentValues cv = new ContentValues();
        cv.put("userName", bean.userName);
        cv.put("nickName", bean.nickName);
        cv.put("sex", bean.sex);
        cv.put("signature", bean.signature);
        db.insert(SQLiteHelper.U_USERINFO, null, cv);
    }

    //获取个人资料信息
    public UserBean getUserInfo(String userName) {
    														//获取对应用户名的个人信息
        String sql = "SELECT * FROM " + SQLiteHelper.U_USERINFO + " WHERE userName=?"; 
        Cursor cursor = db.rawQuery(sql,new String[]{userName});
        UserBean bean = null;
        while (cursor.moveToNext()){
            bean = new UserBean();
            bean.userName=cursor.getString(cursor.getColumnIndex("userName"));
            bean.nickName=cursor.getString(cursor.getColumnIndex("nickName"));
            bean.sex=cursor.getString(cursor.getColumnIndex("sex"));
            bean.signature=cursor.getString(cursor.getColumnIndex("signature"));
        }
        cursor.close();
        return bean;
    }

    //修改资料
    public void updateUserInfo(String key, String value, String userName) {
        ContentValues cv = new ContentValues();
        cv.put(key, value);
        db.update(SQLiteHelper.U_USERINFO, cv, "userName = ?", new String[]{userName});
    }
    
}

5、个人资料界面逻辑代码——UserInfoActivity.java

package com.boxuegu.activity;

import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.graphics.Color;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.os.Bundle;
import android.view.View;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.boxuegu.R;
import com.boxuegu.bean.UserBean;
import com.boxuegu.utils.AnalysisUtils;
import com.boxuegu.utils.DBUtils;

public class UserInfoActivity extends AppCompatActivity implements View.OnClickListener {

    private TextView tv_user_name;
    private TextView tv_signature;
    private RelativeLayout rl_signature;
    private TextView tv_sex;
    private RelativeLayout rl_sex;
    private TextView tv_nickName;
    private RelativeLayout rl_nickName;
    private TextView tv_back;
    private TextView tv_main_title;
    private RelativeLayout rl_title_bar;
    private String spUserName;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_user_info);
        //设置界面为竖屏
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
        spUserName = AnalysisUtils.readLoginUserName(this);
        init();
        initData();
        setListener();
    }

    //初始化控件
    private void init() {
        tv_back = (TextView) findViewById(R.id.tv_back);
        tv_main_title = (TextView) findViewById(R.id.tv_main_title);
        tv_main_title.setText("个人资料");
        rl_title_bar = (RelativeLayout) findViewById(R.id.title_bar);
        rl_title_bar.setBackgroundColor(Color.parseColor("##FF9900"));
        rl_nickName = (RelativeLayout) findViewById(R.id.rl_nickName);
        tv_nickName = (TextView) findViewById(R.id.tv_nickName);
        rl_sex = (RelativeLayout) findViewById(R.id.rl_sex);
        tv_sex = (TextView) findViewById(R.id.tv_sex);
        rl_signature = (RelativeLayout) findViewById(R.id.rl_signature);
        tv_signature = (TextView) findViewById(R.id.tv_signature);
        tv_user_name = (TextView) findViewById(R.id.tv_user_name);
       

    }
    
    //从数据库中获取数据
    private  void initData(){
        UserBean bean = null;
        bean  = DBUtils.getInstance(this).getUserInfo(spUserName);
        //首先判断一下数据库中是否有数据
        if(bean ==null){
            bean = new UserBean();
            bean.userName = spUserName; //用户名不可以修改
            bean.nickName = "这个是你的昵称";
            //默认为男
            bean.sex = "男";
            bean.signature = "这个是你的签名";
            //保存用户信息到数据库
            DBUtils.getInstance(this).saveUserInfo(bean);
        }
        setValue(bean);
    }
    
    //为界面控件设置值
    public void setValue(UserBean bean) {
        tv_nickName.setText(bean.nickName);
        tv_sex.setText(bean.sex);
        tv_signature.setText(bean.signature);
        tv_user_name.setText(bean.userName);
    }
    
    //设置界面的点击监听事件
    private void setListener() {
        tv_back.setOnClickListener(this);
        rl_nickName.setOnClickListener(this);
        rl_sex.setOnClickListener(this);
        rl_signature.setOnClickListener(this);
    }

    //控件的点击事件
    @Override
    public void onClick(View v) {
        switch (v.getId()){
           //返回键的点击事件
            case R.id.tv_back:
                this.finish();
                break;
                
            //昵称的点击事件
            case R.id.rl_nickName:   
                break;
                
            //性别的点击事件 
            case R.id.rl_sex:
                String sex = tv_sex.getText().toString();
                sexDialog(sex);
                break;
                
            //签名的点击事件 
            case R.id.rl_signature: 
                break;
            default:
                break;
        }
    }

    //修改性别的弹出框
    private void sexDialog(String sex) {
        int sexFlag = 0;
        if("男".equals(sex)){
            sexFlag = 0;
        }else if("女".equals(sex)){
            sexFlag = 1;
        }
        final String items[] = {"男","女"};
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle("性别"); //设置标题
        builder.setSingleChoiceItems(items, sexFlag, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();
                Toast.makeText(UserInfoActivity.this,items[which],Toast.LENGTH_SHORT).show();;
                setSex(items[which]);
            }
        });
        builder.show();
    }
    
    //更新界面上的性别数据
    private void setSex(String sex) {
        tv_sex.setText(sex);
        //更新数据库中的性别数据
        DBUtils.getInstance(this).updateUserInfo("sex",sex,spUserName);
    }
}

6、修改我的界面代码

个人资料界面是通过点击用户头像进行跳转的,找到MyInfoView.java文件的initView()方法,在注释//已登录跳转到个人资料界面下方添加如下代码:
Intent intent = new Intent(mContext, UserInfoActivity.class);
mContext.startActivity(intent);

二、资料修改界面

1、个人资料修改界面

(1)、创建个人资料修改界面

com.boxuegu.activity包中创建一个Java类。命名为ChangeUserInfoActivity。在res/layout文件夹下面创建布局文件,命名为activity_change_user_info

(2)、导入界面图片

将所需界面图片info_delete.png导入到drawable文件夹中。

(3)、资料修改界面代码——activity_change_user_info.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#eeeeee">
    <include layout="@layout/main_title_bar"/>
    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:gravity="center_vertical"
        android:orientation="horizontal">
        <EditText
            android:id="@+id/et_content"
            android:layout_width="match_parent"
            android:layout_height="50dp"
            android:layout_gravity="center_horizontal"
            android:background="@android:color/white"
            android:gravity="center_vertical"
            android:paddingLeft="10dp"
            android:singleLine="true"
            android:textColor="#737373"
            android:textSize="14sp"/>
        <ImageView
            android:id="@+id/iv_delete"
            android:layout_width="27dp"
            android:layout_height="27dp"
            android:layout_marginLeft="-40dp"
            android:src="@drawable/info_delete"/>
    </LinearLayout>

</LinearLayout>

2、资料修改界面逻辑代码——ChangeUserInfoActivity.java

package com.boxuegu.activity;

import android.content.Intent;
import android.content.pm.ActivityInfo;
import  com.boxuegu.R;
import android.graphics.Color;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.text.Editable;
import android.text.Selection;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;

public class ChangeUserInfoActivity extends AppCompatActivity {
    private TextView tv_main_title,tv_save;
    private RelativeLayout rl_title_bar;
    private TextView tv_back;
    private String title,content;
    private int flag;  //flag为1时表示修改昵称,为2时表示修改签名
    private EditText et_content;
    private ImageView iv_delete;
    @Override
    protected void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_change_user_info);
        //设置界面为竖屏
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
        init();
    }

    private void init(){
    	//从个人资料界面传递过来的标题和内容
        title = getIntent().getStringExtra("title");
        content = getIntent().getStringExtra("content");
        flag = getIntent().getIntExtra("flag",0);
        tv_main_title = (TextView) findViewById(R.id.tv_main_title);
        tv_main_title.setText(title);
        rl_title_bar = (RelativeLayout) findViewById(R.id.title_bar);
        rl_title_bar.setBackgroundColor(Color.parseColor("#FF9900"));
        tv_back = (TextView) findViewById(R.id.tv_back);
        tv_save = (TextView) findViewById(R.id.tv_save);
        tv_save.setVisibility(View.VISIBLE);
        et_content = (EditText) findViewById(R.id.et_content);
        iv_delete = (ImageView) findViewById(R.id.iv_delete);
        if (!TextUtils.isEmpty(content)){
            et_content.setText(content);
            et_content.setSelection(content.length());
        }
        contentListener();
        tv_back.setOnClickListener(new android.view.View.OnClickListener(){
            @Override
            public void onClick(android.view.View v){
                ChangeUserInfoActivity.this.finish();
            }
        });
        iv_delete.setOnClickListener(new android.view.View.OnClickListener() {
            @Override
            public void onClick(android.view.View v) {
                et_content.setText("");
            }
        });
        tv_save.setOnClickListener(new android.view.View.OnClickListener() {
            @Override
            public void onClick(android.view.View view) {
                Intent data = new Intent();
                String etContent = et_content.getText().toString().trim();
                switch (flag){
                    case 1:
                        if (!TextUtils.isEmpty(etContent)){
                            data.putExtra("nickName",etContent);
                            setResult(RESULT_OK,data);
                            Toast.makeText(ChangeUserInfoActivity.this,"保存成功",Toast.LENGTH_SHORT).show();
                            ChangeUserInfoActivity.this.finish();
                        }else {
                            Toast.makeText(ChangeUserInfoActivity.this,"昵称不能为空",Toast.LENGTH_SHORT).show();
                        }
                        break;
                    case 2:
                        if (!TextUtils.isEmpty(etContent)){
                            data.putExtra("signature",etContent);
                            setResult(RESULT_OK,data);
                            Toast.makeText(ChangeUserInfoActivity.this,"保存成功",Toast.LENGTH_SHORT).show();
                            ChangeUserInfoActivity.this.finish();
                        }else {
                            Toast.makeText(ChangeUserInfoActivity.this,"签名不能为空",Toast.LENGTH_SHORT).show();
                        }
                        break;
                }
            }
        });
    }
    
    //监听个人资料修改界面输入的文字
    public void contentListener(){
        et_content.addTextChangedListener(new TextWatcher() {
            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                Editable editable = et_content.getText();
                int len = editable.length();
                if (len>0){  //输入的文本的长度
                    iv_delete.setVisibility(View.VISIBLE);
                }else {
                    iv_delete.setVisibility(View.GONE);
                }
                switch (flag){
                    case 1:  //1代表修改昵称
                        if (len>8){    //昵称最多8个文字,超过的部分需要进行截取
                            int selEndIndex = Selection.getSelectionEnd(editable);
                            String str = editable.toString();
                            //截取新字符串
                            String newStr = str.substring(0,8);
                            et_content.setText(newStr);
                            editable = et_content.getText();
                            //新字符串的长度
                            int newLen = editable.length();
                            //旧光标位置超过新字符串的位置
                            if (selEndIndex>newLen){
                                selEndIndex = editable.length();
                            }
                            //设置新光标所在位置
                            Selection.setSelection(editable,selEndIndex);
                        }
                        break;
                        
                    case 2: //2代表修改签名
                        if (len>16){  //昵称最多16个文字,超过的部分需要进行截取
                            int selEndIndex = Selection.getSelectionEnd(editable);
                            String str = editable.toString();
                          //截取新字符串
                            String newStr = str.substring(0,16);
                            et_content.setText(newStr);
                            editable = et_content.getText();
                          //新字符串的长度
                            int newLen = editable.length();
                          //旧光标位置超过新字符串的位置
                            if (selEndIndex>newLen){
                                selEndIndex = editable.length();
                            }
                          //设置新光标所在位置
                            Selection.setSelection(editable,selEndIndex);
                        }
                        break;
                    default:
                        break;
                }
            }

            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            }

            @Override
            public void afterTextChanged(Editable arg0) {
            }
        });
    }

}

3、修改个人资料界面代码

(1)、找到UserInfoActivity.java文件,在 private String spUserName;后面添加以下代码:
private static  final int  CHANGE_NICKNAME = 1;//修改昵称的自定义常量
private static  final int  CHANGE_SIGNATURE = 2;//修改签名的自定义常量
(2)、找到UserInfoActivity.java文件,创建一个enterActivityForResult方法用来自定义跳转
   //自定义跳转方法 
    private void enterActivityForResult(Class<?> to,int requestCode,Bundle b){
        Intent i = new Intent(this,to);  //to标识需要跳转到的界面
        i.putExtras(b);  //b表示跳转时传递的参数
        startActivityForResult(i,requestCode);  //requestCode表示一个请求码

    }
(3)、找到UserInfoActivity.java文件,找到onClick()方法,在注释//昵称的点击事件下方添加如下代码:
String name = tv_nickName.getText().toString();//获取昵称控件上的数据
Bundle bdName = new Bundle();
bdName.putString("content",name);  //传递界面上的昵称数据
bdName.putString("title","昵称");  //传递界面的标题
bdName.putInt("flag",1);  //flag 传递1表示是昵称
//跳转到个人资料修改界面
enterActivityForResult(ChangeUserInfoActivity.class,CHANGE_NICKNAME,bdName);
(4)、找到UserInfoActivity.java文件,找到onClick()方法,在注释//签名的点击事件下方添加如下代码:
String signature = tv_signature.getText().toString();//获取签名控件上的数据
Bundle bdSignature = new Bundle();
bdSignature.putString("content",signature);//传递界面上的签名数据
bdSignature.putString("title","签名"); //传递界面的标题
bdSignature.putInt("flag",2);//flag 传递2表示是签名
//跳转到个人资料修改界面
enterActivityForResult(ChangeUserInfoActivity.class,CHANGE_SIGNATURE,bdSignature);
(5)、找到UserInfoActivity.java文件,在UserInfoActivity类中重写onActivityResult()方法,添加如下代码:
//资料修改以后回传数据到界面 
    private String new_info;  //最新数据
    @Override
    protected  void  onActivityResult(int requestCode,int resultCode,Intent data){
        super.onActivityResult(requestCode,resultCode,data);
        switch (requestCode){
            case CHANGE_NICKNAME:
                if(data!=null){
                    new_info = data.getStringExtra("nickName");//从个人资料界面回传过来的数据
                    if(TextUtils.isEmpty(new_info)||new_info==null){
                        return;
                    }
                    tv_nickName.setText(new_info);
                    //更新数据库中的呢称字段
                    DBUtils.getInstance(UserInfoActivity.this).updateUserInfo("nickName", new_info,spUserName);
                }

                break;
            case CHANGE_SIGNATURE:

                if(data!=null){
                    new_info = data.getStringExtra("signature");//从个人资料界面回传过来的数据
                    if(TextUtils.isEmpty(new_info)||new_info==null){
                        return;
                    }
                    tv_signature.setText(new_info);
                    //更新数据库中的签名字段
                    DBUtils.getInstance(UserInfoActivity.this).updateUserInfo("signature", new_info,spUserName);
                }

                break;
        }

    }

三、运行效果

在这里插入图片描述

Android项目实战系列—基于博学谷 开源地址

image               
image


http://www.niftyadmin.cn/n/3649633.html

相关文章

[J2ME]VideoCoolala(MobileWebCam)开源说明

不知道80/20原理最初的说法是怎样的&#xff0c;后来有了很多变种。说一种比较通用的吧&#xff0c;你care 100的东西&#xff0c;可以产生100的结果&#xff0c;但这100结果中&#xff0c;有80是你所care的100中的20带来的&#xff1b;剩下20是其余80带来的。于是就有人说了&a…

node.js启动应用命令_如何使用Node.js构建命令行应用程序

node.js启动应用命令As a developer, chances are you spend most of your time in your terminal, typing in commands to help you get around some tasks. 作为开发人员&#xff0c;您很可能会花费大部分时间在终端上&#xff0c;输入命​​令来帮助您解决一些任务。 Some …

[p2p]手机是否可以通过JXTA网络与PC机/PocketPC/WindowsMobile实现P2P呢?

本文只是探讨一下这种可能性。粗粗地看了JXTA&#xff0c;他的目标很宏大&#xff0c;不局限于各种设备&#xff0c;不局限于各种平台&#xff0c;只要能够保持心跳&#xff0c;就算是P2P的一个对等实体。下载并运行了myJXTA&#xff0c;还可以。又看了JXTA的J2ME实现&#xff…

Android项目实战系列—基于博学谷(六)习题模块

由于这个模块内容较多,篇幅较长&#xff0c;请耐心阅读。 习题模块分为两个部分 习题列表界面 习题详情界面 一、习题列表界面 1、习题界面 &#xff08;1&#xff09;、创建习题界面 在res/layout文件夹中&#xff0c;新建一个布局文件&#xff0c;命名为main_view_exercis…

dart mixins_Dart中的Mixins简介

dart mixinsSome of the best reasons for using object-oriented programming (OOP) are its techniques for helping to keep our code clean and DRY. We’re going to explore some of Dart’s strategies for making your code reusable over separate classes. 使用面向对…