当前位置: 首页 > news >正文

移动应用开发课程第六次实验:为实验2添加登陆页面,用SQList存储好友基本信息

1、在Android Studio中,请在第二次实验成果的基础上完成以下实验要求。

向右滑动

请添加登录页面。在登录页面中,如果用户输入的用户名和密码正确,则跳转至如上图所示的好友列表,并记录用户的登录信息,在用户第一次登录成功后再次打开App时,直接登录进入到好友列表页面[1];如果用户输入的用户名和密码错误,则以Toast方式提示用户输入的用户名或密码错误。

成功登录进入后,侧滑菜单要求仍然可用。

使用SQLite构建内联数据库,其中存储好友基本信息(好友头像、好友名称、最后一次联系的单条消息、最后一次联系的时间)。

在登录进入后,通过SQLite数据库连接读取好友列表数据(5条以上)[2],并以List方式显示在页面上。

3、注意:

① 请将补充的图片素材放入“根目录/Extra”;

② 请将实验报告放入“根目录/Doc”。

运行效果:

文件目录

在实验2中只建立了一个fragment,在这此实验为每一页创建了fragment,但除了XiaoXiFragment,其他的fragment没有写入什么东西。沿用实验2的代码没有任何更改,这里新加了几个文件。

DatabaseHelper.java

package com.example.TheSixthExperiment;import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;public class DatabaseHelper extends SQLiteOpenHelper {private static final String DATABASE_NAME = "friends_db.db";private static final int DATABASE_VERSION = 1;// SQL语句创建表private static final String TABLE_CREATE ="CREATE TABLE friends (" +"id INTEGER PRIMARY KEY AUTOINCREMENT, " +"avatar BLOB, " +"name TEXT, " +"last_message TEXT, " +"last_contact TIMESTAMP);";public DatabaseHelper(Context context) {super(context, DATABASE_NAME, null, DATABASE_VERSION);}@Overridepublic void onCreate(SQLiteDatabase db) {db.execSQL(TABLE_CREATE);}@Overridepublic void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {// 如果数据库版本发生变化,删除旧表并重新创建db.execSQL("DROP TABLE IF EXISTS friends");onCreate(db);}// 清空friends表中的数据,但不删除表本身public void clearDatabase(){SQLiteDatabase db = getWritableDatabase();// 使用DELETE语句清空表中的数据String deleteSQL = "DELETE FROM friends";db.execSQL(deleteSQL);}
}

Friend.java

package com.example.TheSixthExperiment;public class Friend {private byte[] avatar;private String name;private String lastMessage;private String lastContact;public byte[] getAvatar() { return avatar; }public void setAvatar(byte[] avatar) { this.avatar = avatar; }public String getName() { return name; }public void setName(String name) { this.name = name; }public String getLastMessage() { return lastMessage; }public void setLastMessage(String lastMessage) { this.lastMessage = lastMessage; }public String getLastContact() { return lastContact; }public void setLastContact(String lastContact) { this.lastContact = lastContact; }
}

FriendAdapter.java

package com.example.TheSixthExperiment;import android.content.Context;
import android.graphics.BitmapFactory;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;import java.util.List;public class FriendAdapter extends RecyclerView.Adapter<FriendAdapter.FriendViewHolder> {private Context context;private List<Friend> friendList;public FriendAdapter(Context context, List<Friend> friendList) {this.context = context;this.friendList = friendList;}@NonNull@Overridepublic FriendViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {View view = LayoutInflater.from(context).inflate(R.layout.friend_item, parent, false);return new FriendViewHolder(view);}@Overridepublic void onBindViewHolder(@NonNull FriendViewHolder holder, int position) {Friend friend = friendList.get(position);holder.avatarImageView.setImageBitmap(BitmapFactory.decodeByteArray(friend.getAvatar(), 0, friend.getAvatar().length));holder.nameTextView.setText(friend.getName());holder.lastMessageTextView.setText(friend.getLastMessage());holder.lastContactTextView.setText(friend.getLastContact());}@Overridepublic int getItemCount() {return friendList.size();}public static class FriendViewHolder extends RecyclerView.ViewHolder {ImageView avatarImageView;TextView nameTextView;TextView lastMessageTextView;TextView lastContactTextView;public FriendViewHolder(@NonNull View itemView) {super(itemView);avatarImageView = itemView.findViewById(R.id.iv_touxiang);nameTextView = itemView.findViewById(R.id.tv_nicheng);lastMessageTextView = itemView.findViewById(R.id.tv_xiaoxi);lastContactTextView = itemView.findViewById(R.id.tv_shijian);}}
}

LoginActivity.java

package com.example.TheSixthExperiment;import androidx.appcompat.app.AppCompatActivity;import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Locale;public class LoginActivity extends AppCompatActivity {private EditText etUsername, etPassword;private Button btnLogin;private DatabaseHelper dbHelper;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_login);etUsername = findViewById(R.id.et_username);etPassword = findViewById(R.id.et_password);btnLogin = findViewById(R.id.btn_login);SharedPreferences sharedPreferences = getSharedPreferences("MyAppPref", MODE_PRIVATE);boolean isLoggedIn = sharedPreferences.getBoolean("isLoggedIn", false);//isLoggedIn=false;//如果需要每次打开软件看到登陆界面if (isLoggedIn) {Intent intent = new Intent(LoginActivity.this, MainActivity.class);startActivity(intent);finish();}btnLogin.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {String username = etUsername.getText().toString();String password = etPassword.getText().toString();if ("cust".equals(username) && "12345".equals(password)) {//同户名和密码位置,在此处进行更改SharedPreferences.Editor editor = sharedPreferences.edit();editor.putBoolean("isLoggedIn", true);editor.apply();addFriendData();Intent intent = new Intent(LoginActivity.this, MainActivity.class);startActivity(intent);finish();} else {Toast.makeText(LoginActivity.this, "用户名或密码错误", Toast.LENGTH_SHORT).show();}}private void addFriendData() {dbHelper = new DatabaseHelper(LoginActivity.this);dbHelper.clearDatabase();insertFriend(getBitmapAsByteArray(R.drawable.touxiang1), "马云", "支付宝转给你一千万,记得查收一下", "2024-10-20");insertFriend(getBitmapAsByteArray(R.drawable.touxiang2), "马化腾", "以后还要你多多照顾", "2024-10-18");insertFriend(getBitmapAsByteArray(R.drawable.touxiang3), "范冰冰", "明天你有空吗", "2024-10-10");insertFriend(getBitmapAsByteArray(R.drawable.touxiang4), "雷军", "谢谢你对小米的照顾", "2024-10-8");insertFriend(getBitmapAsByteArray(R.drawable.touxiang5), "巴菲特", "有空能一起吃个饭吗?", "2024-10-8");insertFriend(getBitmapAsByteArray(R.drawable.touxiang6), "比尔盖茨", "微软不能没有你啊", "2024-10-5");insertFriend(getBitmapAsByteArray(R.drawable.touxiang7), "马斯克", "你好", "2024-9-28");insertFriend(getBitmapAsByteArray(R.drawable.touxiang9), "张一鸣", "有问题想要请教你", "2024-9-28");insertFriend(getBitmapAsByteArray(R.drawable.touxiang10), "乔布斯", "你想接手苹果公司吗", "2024-9-26");insertFriend(getBitmapAsByteArray(R.drawable.touxiang11), "乔丹", "我会回来的", "2024-9-24");insertFriend(getBitmapAsByteArray(R.drawable.touxiang12), "周鸿祎", "谢谢你对360的支持", "2024-9-20");insertFriend(getBitmapAsByteArray(R.drawable.touxiang13), "王建林", "谢谢你借钱给我", "2024-9-20");insertFriend(getBitmapAsByteArray(R.drawable.touxiang8), "迪迦凹凸曼", "什么时候和我回光之国?", "2024-9-1");}});}private void insertFriend(byte[] avatar, String name, String lastMessage, String lastContact) {SQLiteDatabase db = dbHelper.getWritableDatabase();ContentValues values = new ContentValues();values.put("avatar", avatar);values.put("name", name);values.put("last_message", lastMessage);values.put("last_contact", lastContact);db.insert("friends", null, values);}public byte[] getBitmapAsByteArray(int resourceId) {InputStream inputStream = getResources().openRawResource(resourceId);byte[] avatarData = null;try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) {int bufferSize = 1024;byte[] buffer = new byte[bufferSize];int length;while ((length = inputStream.read(buffer)) > 0) {byteArrayOutputStream.write(buffer, 0, length);}avatarData = byteArrayOutputStream.toByteArray();} catch (IOException e) {e.printStackTrace();} finally {try {if (inputStream != null) {inputStream.close();}} catch (IOException ex) {ex.printStackTrace();}}return avatarData;}
}

MainActivity.java

package com.example.TheSixthExperiment;import android.app.AlertDialog;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.HorizontalScrollView;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;public class MainActivity extends AppCompatActivity {private HorizontalScrollView horizontalScrollView;private ImageView erweima, quxiao;private LinearLayout llxiaoxi, llpindao, lllianxiren, lldongtai, button1, button2, button3, button4, button5;private ImageView ivxiaoxi, ivpindao, ivlianxiren, ivdonngtai;private TextView tvxiaoxi, tvpindao, tvlianxiren, tvdongtai;FragmentManager fragmentManager;FragmentTransaction fragmentTransaction;DongTaiFragment dongTaiFragment;LianXiRenFragment lianXiRenFragment;PinDaoFragment pinDaoFragment;XiaoXiFragment xiaoXiFragment;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);initView();initEvent();setupButtonListeners();}private void initEvent() {fragmentManager = getSupportFragmentManager();fragmentTransaction = fragmentManager.beginTransaction();ivxiaoxi.setImageResource(R.drawable.xiaoxi2);tvxiaoxi.setTextColor(getResources().getColor(R.color.blue));fragmentTransaction.replace(R.id.fcv_fragment, xiaoXiFragment).commit();}private void initView() {llxiaoxi = findViewById(R.id.ll_xiaoxi);ivxiaoxi = findViewById(R.id.iv_xiaoxi);tvxiaoxi = findViewById(R.id.tv_xiaoxi);llpindao = findViewById(R.id.ll_pindao);ivpindao = findViewById(R.id.iv_pindao);tvpindao = findViewById(R.id.tv_pindao);lllianxiren = findViewById(R.id.ll_lianxiren);ivlianxiren = findViewById(R.id.iv_lianxiren);tvlianxiren = findViewById(R.id.tv_lianxiren);lldongtai = findViewById(R.id.ll_dongtai);ivdonngtai = findViewById(R.id.iv_dongtai);tvdongtai = findViewById(R.id.tv_dongtai);erweima = findViewById(R.id.erweima);quxiao = findViewById(R.id.quxiao);button1 = findViewById(R.id.button1);button2 = findViewById(R.id.button2);button3 = findViewById(R.id.button3);button4 = findViewById(R.id.button4);button5 = findViewById(R.id.button5);horizontalScrollView = findViewById(R.id.mhsv);dongTaiFragment=new DongTaiFragment();lianXiRenFragment=new LianXiRenFragment();pinDaoFragment=new PinDaoFragment();xiaoXiFragment=new XiaoXiFragment();}private void setupButtonListeners() {button1.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) { showToast("笑脸"); }});button2.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {showToast("电话");}});button3.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {showToast("点赞");}});button4.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {showToast("发现");}});button5.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {showToast("标签");}});erweima.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {horizontalScrollView.smoothScrollTo(10000, 0);showImageDialog();}});quxiao.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {horizontalScrollView.smoothScrollTo(10000, 0);}});lllianxiren.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {initDaoHang();fragmentManager = getSupportFragmentManager();fragmentTransaction = fragmentManager.beginTransaction();fragmentTransaction.replace(R.id.fcv_fragment, lianXiRenFragment).commit();ivlianxiren.setImageResource(R.drawable.lianxiren2);tvlianxiren.setTextColor(getResources().getColor(R.color.blue));}});llxiaoxi.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {initDaoHang();fragmentManager = getSupportFragmentManager();fragmentTransaction = fragmentManager.beginTransaction();fragmentTransaction.replace(R.id.fcv_fragment, xiaoXiFragment).commit();ivxiaoxi.setImageResource(R.drawable.xiaoxi2);tvxiaoxi.setTextColor(getResources().getColor(R.color.blue));}});llpindao.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {initDaoHang();fragmentManager = getSupportFragmentManager();fragmentTransaction = fragmentManager.beginTransaction();fragmentTransaction.replace(R.id.fcv_fragment, pinDaoFragment).commit();ivpindao.setImageResource(R.drawable.pingdao2);tvpindao.setTextColor(getResources().getColor(R.color.blue));}});lldongtai.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {initDaoHang();fragmentManager = getSupportFragmentManager();fragmentTransaction = fragmentManager.beginTransaction();fragmentTransaction.replace(R.id.fcv_fragment, dongTaiFragment).commit();ivdonngtai.setImageResource(R.drawable.dongtai2);tvdongtai.setTextColor(getResources().getColor(R.color.blue));}});}private void showToast(String message) {Toast.makeText(this, message, Toast.LENGTH_SHORT).show();}private void showImageDialog() {AlertDialog.Builder builder = new AlertDialog.Builder(this);LayoutInflater inflater = getLayoutInflater();View dialogView = inflater.inflate(R.layout.custom_dialog_layout, null);ImageView dialogImageView = dialogView.findViewById(R.id.dialog_image_view);dialogImageView.setImageResource(R.drawable.cust);builder.setView(dialogView).setCancelable(true);AlertDialog alertDialog = builder.create();alertDialog.show();}private void initDaoHang() {ivlianxiren.setImageResource(R.drawable.lianxiren1);tvlianxiren.setTextColor(getResources().getColor(R.color.black));ivpindao.setImageResource(R.drawable.pingdao1);tvpindao.setTextColor(getResources().getColor(R.color.black));ivdonngtai.setImageResource(R.drawable.dongtai1);tvdongtai.setTextColor(getResources().getColor(R.color.black));ivxiaoxi.setImageResource(R.drawable.xiaoxi1);tvxiaoxi.setTextColor(getResources().getColor(R.color.black));}
}

XiaoXiFragment.java

package com.example.TheSixthExperiment;import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;import java.util.ArrayList;
import java.util.List;public class XiaoXiFragment extends Fragment {private RecyclerView recyclerView;private FriendAdapter friendAdapter;private List<Friend> friendList;private DatabaseHelper dbHelper;@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {// 初始化布局View view = inflater.inflate(R.layout.fragment_xiao_xi, container, false);recyclerView = view.findViewById(R.id.recyclerView);dbHelper = new DatabaseHelper(getActivity()); // 使用getActivity()获取上下文// 从数据库读取数据friendList = getFriendsFromDatabase();// 设置RecyclerViewrecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));friendAdapter = new FriendAdapter(getActivity(), friendList);recyclerView.setAdapter(friendAdapter);return view;}private List<Friend> getFriendsFromDatabase() {List<Friend> friends = new ArrayList<>();SQLiteDatabase db = dbHelper.getReadableDatabase();Cursor cursor = db.query("friends", new String[]{"id", "avatar", "name", "last_message", "last_contact"},null, null, null, null, "id ASC");while (cursor.moveToNext()) {Friend friend = new Friend();friend.setAvatar(cursor.getBlob(cursor.getColumnIndex("avatar")));friend.setName(cursor.getString(cursor.getColumnIndex("name")));friend.setLastMessage(cursor.getString(cursor.getColumnIndex("last_message")));friend.setLastContact(cursor.getString(cursor.getColumnIndex("last_contact")));friends.add(friend);}cursor.close();return friends;}
}

MyHorizontalScrollVie.java

package com.example.TheSixthExperiment;import android.content.Context;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.MotionEvent;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.HorizontalScrollView;
import android.widget.LinearLayout;public class MyHorizontalScrollView extends HorizontalScrollView {//滚动条中的水平先行布局private LinearLayout mWrpper;//水平线性布局的左侧菜单menuprivate ViewGroup mMenu;//水平先行布局的右侧线性布局private ViewGroup mContent;//屏幕的宽private int mScreenWidth;//menu的宽离屏幕右侧的距离private int mMenuRightPadding=50;//menu的宽度private int mMenuWidth;private boolean once;/*** 未使用自定义属性时调用* */public MyHorizontalScrollView(Context context, AttributeSet attrs) {super(context, attrs);/** 获取屏幕的宽度* 通过context拿到windowManager,在通过windowManager拿到Metrics,用DisplayMetrics接收* */WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);DisplayMetrics outMetrics = new DisplayMetrics();wm.getDefaultDisplay().getMetrics(outMetrics);mScreenWidth=outMetrics.widthPixels;//把dp转换成pxmMenuRightPadding=(int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 50,context.getResources().getDisplayMetrics());}/** 设置子view的宽和高* */@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {// TODO Auto-generated method stubif(!once){mWrpper=(LinearLayout) getChildAt(0);mMenu=(ViewGroup) mWrpper.getChildAt(0);mContent=(ViewGroup) mWrpper.getChildAt(1);//menu的宽度等于屏幕的宽度减去menu离屏幕右侧的边距mMenuWidth=mMenu.getLayoutParams().width=mScreenWidth;//右边的先行布局的宽度直接等于屏幕的宽度mContent.getLayoutParams().width=mScreenWidth;once=true;}super.onMeasure(widthMeasureSpec, heightMeasureSpec);}/** 通过设置偏移量将menu隐藏* */@Overrideprotected void onLayout(boolean changed, int l, int t, int r, int b) {// TODO Auto-generated method stubsuper.onLayout(changed, l, t, r, b);/** 通过scrollTo(x,y)方法设置屏幕的偏移量,x为正* 内容向左移动* */if(changed){this.scrollTo(mMenuWidth, 0);}}/** 因为HorizontalScrollView自己控制move和down的事件* 所以我们还要判断一下up.如果当前的x偏移量大于menu宽度的一半* 隐藏menu,否则显示menu* */@Overridepublic boolean onTouchEvent(MotionEvent ev) {// TODO Auto-generated method stubint action=ev.getAction();switch(action){case MotionEvent.ACTION_UP:int scrollX=getScrollX();if(scrollX>=mMenuWidth/2){this.smoothScrollTo(mMenuWidth, 0);}else{this.smoothScrollTo(0, 0);}return true;}return super.onTouchEvent(ev);}
}

activity_ login.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="vertical"android:padding="16dp"><EditTextandroid:id="@+id/et_username"android:layout_width="match_parent"android:layout_height="wrap_content"android:hint="Username:cust"android:inputType="text" /><EditTextandroid:id="@+id/et_password"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginTop="16dp"android:hint="Password:12345"android:inputType="textPassword" /><Buttonandroid:id="@+id/btn_login"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginTop="16dp"android:text="Login" /></LinearLayout>

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<com.example.TheSixthExperiment.MyHorizontalScrollView xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"android:id="@+id/mhsv"android:layout_width="match_parent"android:layout_height="match_parent"android:scrollbars="none"><LinearLayoutandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center_vertical"android:orientation="horizontal"><include layout="@layout/meum" /><LinearLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><androidx.fragment.app.FragmentContainerViewandroid:id="@+id/fcv_fragment"android:layout_width="match_parent"android:layout_height="match_parent"android:layout_weight="1"/><includelayout="@layout/daohang"android:layout_width="match_parent"android:layout_height="wrap_content" /></LinearLayout></LinearLayout>
</com.example.TheSixthExperiment.MyHorizontalScrollView>

custom _dialog_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="fill_parent"android:layout_height="fill_parent"><ImageViewandroid:id="@+id/dialog_image_view"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_centerInParent="true"android:src="@drawable/cust" />
</RelativeLayout>

daohang.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="wrap_content"android:layout_alignParentBottom="true"android:background="@color/white"android:orientation="horizontal"><LinearLayoutandroid:id="@+id/ll_xiaoxi"android:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="1"android:background="?attr/selectableItemBackground"android:clickable="true"android:gravity="center_horizontal"android:orientation="vertical"><ImageViewandroid:id="@+id/iv_xiaoxi"android:layout_width="40dp"android:layout_height="40dp"android:src="@drawable/xiaoxi1" /><TextViewandroid:id="@+id/tv_xiaoxi"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="消息"android:textSize="20sp" /></LinearLayout><LinearLayoutandroid:id="@+id/ll_pindao"android:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="1"android:background="?attr/selectableItemBackground"android:clickable="true"android:gravity="center_horizontal"android:orientation="vertical"><ImageViewandroid:id="@+id/iv_pindao"android:layout_width="40dp"android:layout_height="40dp"android:src="@drawable/pingdao1" /><TextViewandroid:id="@+id/tv_pindao"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="频道"android:textSize="20sp" /></LinearLayout><LinearLayoutandroid:id="@+id/ll_lianxiren"android:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="1"android:background="?attr/selectableItemBackground"android:clickable="true"android:gravity="center_horizontal"android:orientation="vertical"><ImageViewandroid:id="@+id/iv_lianxiren"android:layout_width="40dp"android:layout_height="40dp"android:src="@drawable/lianxiren1" /><TextViewandroid:id="@+id/tv_lianxiren"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="联系人"android:textSize="20sp" /></LinearLayout><LinearLayoutandroid:id="@+id/ll_dongtai"android:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="1"android:background="?attr/selectableItemBackground"android:clickable="true"android:gravity="center_horizontal"android:orientation="vertical"><ImageViewandroid:id="@+id/iv_dongtai"android:layout_width="40dp"android:layout_height="40dp"android:src="@drawable/dongtai1" /><TextViewandroid:id="@+id/tv_dongtai"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="动态"android:textSize="20sp" /></LinearLayout></LinearLayout>

fragment_ xiao_ xi.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:id="@+id/fragment_root_view"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".XiaoXiFragment"><androidx.recyclerview.widget.RecyclerViewandroid:id="@+id/recyclerView"android:layout_width="match_parent"android:layout_height="match_parent"android:padding="8dp"android:scrollbars="vertical" /></FrameLayout>

friend_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="wrap_content"><ImageViewandroid:id="@+id/iv_touxiang"android:layout_width="60dp"android:layout_height="60dp"android:padding="5dp" /><TextViewandroid:id="@+id/tv_nicheng"android:layout_width="wrap_content"android:layout_height="wrap_content"android:textSize="20sp"android:layout_toRightOf="@+id/iv_touxiang"/><TextViewandroid:id="@id/tv_xiaoxi"android:layout_width="wrap_content"android:layout_height="wrap_content"android:textSize="15sp"android:layout_toRightOf="@+id/iv_touxiang"android:layout_below="@+id/tv_nicheng"/><TextViewandroid:id="@+id/tv_shijian"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignParentRight="true"android:layout_marginRight="50dp"android:layout_marginTop="5dp"/></RelativeLayout>

meum.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"android:layout_width="fill_parent"android:layout_height="fill_parent"android:background="#ffffff"android:orientation="vertical"><ImageViewandroid:id="@+id/erweima"android:layout_width="60dp"android:layout_height="60dp"android:layout_alignParentTop="true"android:layout_alignParentRight="true"android:layout_marginTop="163dp"android:padding="10dp"android:src="@drawable/erweima" /><ImageViewandroid:id="@+id/quxiao"android:layout_width="60dp"android:layout_height="60dp"android:layout_alignParentTop="true"android:layout_alignParentRight="true"android:layout_marginRight="3dp"android:clickable="true"android:padding="10dp"android:src="@drawable/quxiao" /><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_alignParentBottom="true"android:layout_marginBottom="175dp"android:orientation="vertical"android:padding="10dp"><LinearLayoutandroid:id="@+id/button1"android:layout_width="match_parent"android:layout_height="wrap_content"android:background="?attr/selectableItemBackground"android:clickable="true"android:orientation="horizontal"><ImageViewandroid:id="@+id/imageView1"android:layout_width="41dp"android:layout_height="41dp"android:src="@drawable/xiaolian"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent"app:layout_constraintWidth_percent="0.3" /><TextViewandroid:id="@+id/textView1"android:layout_width="match_parent"android:layout_height="match_parent"android:paddingLeft="10dp"android:paddingTop="10dp"android:text="笑脸"android:textColor="#000000"app:layout_constraintBottom_toBottomOf="@id/imageView1"app:layout_constraintStart_toEndOf="@id/imageView1"app:layout_constraintTop_toTopOf="parent" /></LinearLayout><LinearLayoutandroid:id="@+id/button2"android:layout_width="match_parent"android:layout_height="wrap_content"android:background="?attr/selectableItemBackground"android:clickable="true"><ImageViewandroid:id="@+id/imageView2"android:layout_width="41dp"android:layout_height="41dp"android:src="@drawable/dianhua"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent"app:layout_constraintWidth_percent="0.3" /> <!-- 可选:设置相对宽度 --><TextViewandroid:id="@+id/textView2"android:layout_width="match_parent"android:layout_height="match_parent"android:paddingLeft="10dp"android:paddingTop="10dp"android:text="电话"android:textColor="#000000"app:layout_constraintBottom_toBottomOf="@id/imageView1"app:layout_constraintStart_toEndOf="@id/imageView1"app:layout_constraintTop_toTopOf="parent" /></LinearLayout><LinearLayoutandroid:id="@+id/button3"android:layout_width="match_parent"android:layout_height="wrap_content"android:background="?attr/selectableItemBackground"android:clickable="true"><ImageViewandroid:id="@+id/imageView3"android:layout_width="41dp"android:layout_height="41dp"android:src="@drawable/dianzan"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent"app:layout_constraintWidth_percent="0.3" /> <!-- 可选:设置相对宽度 --><TextViewandroid:id="@+id/textView3"android:layout_width="match_parent"android:layout_height="match_parent"android:paddingLeft="10dp"android:paddingTop="10dp"android:text="点赞"android:textColor="#000000"app:layout_constraintBottom_toBottomOf="@id/imageView1"app:layout_constraintStart_toEndOf="@id/imageView1"app:layout_constraintTop_toTopOf="parent" /></LinearLayout><LinearLayoutandroid:id="@+id/button4"android:layout_width="match_parent"android:layout_height="wrap_content"android:background="?attr/selectableItemBackground"android:clickable="true"><ImageViewandroid:id="@+id/imageView4"android:layout_width="41dp"android:layout_height="41dp"android:src="@drawable/faxian"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent"app:layout_constraintWidth_percent="0.3" /> <!-- 可选:设置相对宽度 --><TextViewandroid:id="@+id/textView4"android:layout_width="match_parent"android:layout_height="match_parent"android:paddingLeft="10dp"android:paddingTop="10dp"android:text="发现"android:textColor="#000000"app:layout_constraintBottom_toBottomOf="@id/imageView1"app:layout_constraintStart_toEndOf="@id/imageView1"app:layout_constraintTop_toTopOf="parent" /></LinearLayout><LinearLayoutandroid:id="@+id/button5"android:layout_width="match_parent"android:layout_height="wrap_content"android:background="?attr/selectableItemBackground"android:clickable="true"><ImageViewandroid:id="@+id/imageView5"android:layout_width="41dp"android:layout_height="41dp"android:src="@drawable/biaoqian"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent"app:layout_constraintWidth_percent="0.3" /> <!-- 可选:设置相对宽度 --><TextViewandroid:id="@+id/textView5"android:layout_width="match_parent"android:layout_height="match_parent"android:paddingLeft="10dp"android:paddingTop="10dp"android:text="标签"android:textColor="#000000"app:layout_constraintBottom_toBottomOf="@id/imageView1"app:layout_constraintStart_toEndOf="@id/imageView1"app:layout_constraintTop_toTopOf="parent" /></LinearLayout></LinearLayout></RelativeLayout>

colors.xml

<?xml version="1.0" encoding="utf-8"?>
<resources><color name="purple_200">#FFBB86FC</color><color name="purple_500">#FF6200EE</color><color name="purple_700">#FF3700B3</color><color name="teal_200">#FF03DAC5</color><color name="teal_700">#FF018786</color><color name="black">#FF000000</color><color name="white">#FFFFFFFF</color><color name="blue">#1296db</color>
</resources>

AndroidManifest.xml(请注意这个代码的结构)

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"package="com.example.TheSixthExperiment"><applicationandroid:allowBackup="true"android:icon="@mipmap/ic_launcher"android:label="@string/app_name"android:roundIcon="@mipmap/ic_launcher_round"android:supportsRtl="true"android:theme="@style/Theme.TheSecond"><activity android:name="com.example.TheSixthExperiment.LoginActivity"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity><activity android:name="com.example.TheSixthExperiment.MainActivity"></activity></application></manifest>

工程文件

通过网盘分享的文件:TheSixthExperiment.zip
链接:https://pan.baidu.com/s/1_3GeK8TAfbmL1ygiiV7xtQ?pwd=4v6d 提取码: 4v6d

gitee:android studio: 移动应用开发实验代码

相关文章:

移动应用开发课程第六次实验:为实验2添加登陆页面,用SQList存储好友基本信息

1、在Android Studio中&#xff0c;请在第二次实验成果的基础上完成以下实验要求。 向右滑动 请添加登录页面。在登录页面中&#xff0c;如果用户输入的用户名和密码正确&#xff0c;则跳转至如上图所示的好友列表&#xff0c;并记录用户的登录信息&#xff0c;在用户第一次登…...

nextjs增加系统路径前缀(basePath)适配方案

在 Next.js 中&#xff0c;路由是通过文件夹结构来定义的&#xff0c;使用类似于 History 模式的 URL 结构。所以如果想通过nginx来代理一个nextjs开发的系统&#xff0c; 除非直接使用跟路径/来进行代理&#xff0c;否则代理将非常麻烦&#xff0c;这时添加basePath就非常有必…...

嵌入式蓝桥杯学习拓展 LCD翻转显示

通过配置SS和GS两个标志位&#xff0c;实现扫描方向的切换。 将lcd.c的REG_932X_Init函数进行部分修改。 将LCD_WriteReg(R1, 0x0000);修改为LCD_WriteReg(R1,0x0100); 将LCD_WriteReg(R96, 0x2700); 修改为LCD_WriteReg(R96, 0xA700); void REG_932X_Init1(void) {LCD_Wr…...

学习threejs,实现配合使用WebWorker

&#x1f468;‍⚕️ 主页&#xff1a; gis分享者 &#x1f468;‍⚕️ 感谢各位大佬 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍⚕️ 收录于专栏&#xff1a;threejs gis工程师 文章目录 一、&#x1f340;前言1.1 ☘️WebWorker web端多线程 二、…...

TDengine 新功能 复合主键

1. 简介 从 TDengine 3.3.0.0 版本之后&#xff0c;新增了复合主键的功能。 TDengine 原来的时间列是不允许有重复时间戳的&#xff0c;有了复合主键功能后&#xff0c;时间列即允许有重复&#xff0c;重复后的时间戳按紧跟其后第二列主键列的值来确定唯一性。 此功能的常用…...

JVM 面试题

Java 虚拟机&#xff08;JVM&#xff09;是运行 Java 程序的引擎&#xff0c;它是 Java 语言 “一次编译&#xff0c;处处运行” 的核心技术。JVM 的主要任务是将 Java 字节码&#xff08;Bytecode&#xff09;解释成机器码并执行&#xff0c;负责内存管理、线程管理、垃圾回收…...

组件上传图片不回显问题

import { Plus } from "element-plus/icons-vue"; // 图片上传 const img_add ref([]); function httpRequest_add(option) {let dataForm new FormData();dataForm.append("file", option.file);dataForm.append("id", user.data.id);axios({…...

【JavaWeb后端学习笔记】Spring AOP面向切面编程

AOP 1、Spring AOP概述2、SpringAOP快速入门3、SpringAOP核心概念4、通知类型5、通知顺序6、切入点表达式6.1 execution方式6.2 annotation方式 7、连接点 1、Spring AOP概述 AOP&#xff1a;Aspect Oriented Programming&#xff0c;面向特定方法编程。 AOP是通过动态代理技术…...

6.584-Lab5B

6.584-Lab5B Reference CodeReference BlogHomeworkMyself Code Sharded Key/Value Service 梗概 这个图是我从上面参考blog中拿来的&#xff0c;觉得做的不错&#xff0c;借助这张图来讲解一下需要一个什么样的 Service。 ShardCtrler Client&#xff1a; 接收来自客户发出的命…...

OceanBase 的探索与实践

作者&#xff1a;来自 vivo 互联网数据库团队- Xu Shaohui 本文总结了目前我们遇到的痛点问题并通过 OceanBase 的技术方案解决了这些痛点问题&#xff0c;完整的描述了 OceanBase 的实施落地&#xff0c;通过迁移到 OceanBase 实践案例中遇到的问题与解决方案让大家能更好的了…...

安卓调试环境搭建

前言 前段时间电脑重装了系统&#xff0c;最近准备调试一个apk&#xff0c;没想到装环境的过程并不顺利&#xff0c;很让人火大&#xff0c;于是记录一下。 反编译工具下载 下载apktool.bat和apktool.jar 官网地址&#xff1a;https://ibotpeaches.github.io/Apktool/install…...

动画Lottie

Lottie简介 Lottie是一个Airbnb 开发的用于Android&#xff0c;iOS&#xff0c;Web和Windows的库&#xff0c;用于解析使用Bodymovin导出为json的Adobe After Effects动画&#xff0c;并在移动设备和网络上呈现 — GitHub Lottie主要特性 After Effects 兼容性&#xff1a; …...

C++感受14-Hello Object 封装版 - 上

1. 封装即约束——封装和派生、多态的本质区别 一门计算机语言&#xff0c;要如何帮助程序员写出优秀的代码&#xff1f;两个方法&#xff1a;一是给程序员更多能力&#xff0c;二是给程序员更多约束。之前我们学习的派生和多态&#xff0c;更多的是给我们技能&#xff0c;而封…...

网络安全中大数据和人工智能应用实践

传统的网络安全防护手段主要是通过单点的网络安全设备&#xff0c;随着网络攻击的方式和手段不断的变化&#xff0c;大数据和人工智能技术也在最近十年飞速地发展&#xff0c;网络安全防护也逐渐开始拥抱大数据和人工智能。传统的安全设备和防护手段容易形成数据孤岛&#xff0…...

RISC-V架构下OP-TEE 安全系统实践

安全之安全(security)博客目录导读 本篇博客,我们聚焦RISC-V 2024中国峰会上的RISC-V和OP-TEE结合的一个安全系统实践,来自芯来科技桂兵老师。 关于RISC-V TEE(可信执行环境)的相关方案,如感兴趣可参考R...

40分钟学 Go 语言高并发:【实战】分布式缓存系统

【实战课程】分布式缓存系统 一、整体架构设计 首先&#xff0c;让我们通过架构图了解分布式缓存系统的整体设计&#xff1a; 核心组件 组件名称功能描述技术选型负载均衡层请求分发、节点选择一致性哈希缓存节点数据存储、过期处理内存存储 持久化同步机制节点间数据同步…...

[创业之路-186]:《华为战略管理法-DSTE实战体系》-1-为什么UTStarcom死了,华为却活了,而且越活越好?

目录 前言 一、市场定位与战略选择 二、技术创新能力 三、企业文化与团队建设 四、应对危机的能力 五、客户为中心的理念 六、市场适应性与战略灵活性 七、技术创新与研发投入 八、企业文化与团队建设 九、应对危机的能力 前言 UT斯达康&#xff08;UTStarcom&#…...

python如何多行注释

在Python中&#xff0c;多行注释通常有两种方式&#xff1a; 使用三个单引号&#xff08;&#xff09;或三个双引号&#xff08;"""&#xff09;来创建多行字符串&#xff0c;这可以被用来作为多行注释。这种方式在Python中实际上是创建了一个多行的字符串对象…...

前端工程化面试题目常见

前端工程化面试常见题目包括&#xff1a; • 谈谈你对WebPack的认识。 • Webpack打包的流程是什么&#xff1f; • 说说你工作中几个常用的loader。 • 说说HtmlWebpackPlugin插件的作用。 • Webpack支持的脚本模块规范有哪些&#xff1f; • Webpack和gulp/grunt相比有什么特…...

定点数的乘除运算

原码一位乘法 乘积的符号由两个数的符号位异或而成。&#xff08;不参与运算&#xff09;被乘数和乘数均取绝对值参与运算&#xff0c;看作无符号数。乘数的最低位为Yn&#xff1a; 若Yn1&#xff0c;则部分积加上被乘数|x|&#xff0c;然后逻辑右移一位&#xff1b;若Yn0&…...

页面置换算法模拟 最近最久未使用(LRU)算法

最近最久未使用&#xff08;LRU&#xff09;算法是一种基于页面访问历史的页面置换算法。它选择最久未使用的页面进行置换。当需要访问一个不在内存中的页面时&#xff0c;如果内存已满&#xff0c;则选择最久未使用的页面进行置换。LRU算法通过记录页面的访问时间戳来判断页面…...

Ubuntu与Centos系统有何区别?

Ubuntu和CentOS都是基于Linux内核的操作系统&#xff0c;但它们在设计理念、使用场景和技术实现上有显著的区别。以下是详细的对比&#xff1a; 1. 基础和发行版本 Ubuntu&#xff1a; 基于Debian&#xff0c;使用.deb包管理系统。包含两个主要版本&#xff1a; LTS&#xff…...

RK3568平台开发系列讲解(pinctrl 子系统篇)pinctrl_debug

🚀返回专栏总目录 文章目录 1. Overview2. debug信息2.1 pinctrl-devices2.2. pinctrl-handles2.3. pinctrl-handles3. debug信息3.1. 查看(pinctrl_register_pins)注册了哪些pins3.2. 查看pin groups;3.3. 查看每种functions所占用的gpio groups信息:3.4. pinconf沉淀、…...

避大坑!Vue3中reactive丢失响应式的问题

在vue3中,我们定义响应式数据无非是ref和reactive。 但是有的小伙伴会踩雷&#xff01;导致定义的响应式丢失的问题。 reactive丢失响应式的情况1&#xff08;直接赋值&#xff09; 场景: 1.你定义了一个数据:let datareactive({name:"",age:"" }) 2.然后你…...

springSecurity权限控制

权限控制&#xff1a;不同的用户可以使用不同的功能。 我们不能在前端判断用户权限来控制显示哪些按钮&#xff0c;因为这样&#xff0c;有人会获取该功能对应的接口&#xff0c;就不需要通过前端&#xff0c;直接发送请求实现功能了。所以需要在后端进行权限判断。&#xff0…...

Pytorch训练固定随机种子(单卡场景和分布式训练场景)

模型的训练是一个随机过程&#xff0c;固定随机种子可以帮助我们复现实验结果。 接下来介绍一个模型训练过程中固定随机种子的代码&#xff0c;并对每条语句的作用都会进行解释。 def seed_reproducer(seed2333):random.seed(seed)os.environ["PYTHONHASHSEED"] s…...

Conda + JuiceFS :增强 AI 开发环境共享能力

Conda 是当前 AI 应用开发领域中非常流行的环境和包管理系统&#xff0c;因其能够简单便捷地创建与系统资源相隔离的虚拟环境广受欢迎。 Conda 支持在不同的操作系统上重建相同的工作环境&#xff0c;但在环境共享复用方面仍存在一些挑战。比如&#xff0c;在不同机器上复用相…...

人工智能-人机交互的机会

目录 引言HCI领域的发展机会人工智能领域的崛起与机会博雅智信的HCI与AI辅导服务结语 引言 在人类科技不断进步的今天&#xff0c;HCI&#xff08;人机交互&#xff09;和人工智能&#xff08;AI&#xff09;是两个密切相关且充满潜力的领域。HCI研究如何优化人类与计算机之间…...

【系统架构核心服务设计】使用 Redis ZSET 实现排行榜服务

目录 一、排行榜的应用场景 二、排行榜技术的特点 三、使用Redis ZSET实现排行榜 3.1 引入依赖 3.2 配置Redis连接 3.3 创建实体类&#xff08;可选&#xff09; 3.4 编写 Redis 操作服务层 3.5 编写控制器层 3.6 测试 3.6.1 测试 addMovieScore 接口 3.6.2 测试 g…...

elasticsearch基础总结

最近实习&#xff0c;项目用的elasticseatch做的存储库&#xff0c;但是之前对于es接触的不多&#xff0c;查询语法有些不熟&#xff0c;每次想写个DSL查询时都要gpt或者施展搜索大法&#xff0c;所以索性就自己总结总结&#xff0c;以后忘了也方便查。所以这篇文章会持续更新。…...