移动应用开发课程第六次实验:为实验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中,请在第二次实验成果的基础上完成以下实验要求。 向右滑动 请添加登录页面。在登录页面中,如果用户输入的用户名和密码正确,则跳转至如上图所示的好友列表,并记录用户的登录信息,在用户第一次登…...

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

嵌入式蓝桥杯学习拓展 LCD翻转显示
通过配置SS和GS两个标志位,实现扫描方向的切换。 将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
👨⚕️ 主页: gis分享者 👨⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅! 👨⚕️ 收录于专栏:threejs gis工程师 文章目录 一、🍀前言1.1 ☘️WebWorker web端多线程 二、…...

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

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

组件上传图片不回显问题
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:Aspect Oriented Programming,面向特定方法编程。 AOP是通过动态代理技术…...

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

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

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

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

C++感受14-Hello Object 封装版 - 上
1. 封装即约束——封装和派生、多态的本质区别 一门计算机语言,要如何帮助程序员写出优秀的代码?两个方法:一是给程序员更多能力,二是给程序员更多约束。之前我们学习的派生和多态,更多的是给我们技能,而封…...

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

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

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

[创业之路-186]:《华为战略管理法-DSTE实战体系》-1-为什么UTStarcom死了,华为却活了,而且越活越好?
目录 前言 一、市场定位与战略选择 二、技术创新能力 三、企业文化与团队建设 四、应对危机的能力 五、客户为中心的理念 六、市场适应性与战略灵活性 七、技术创新与研发投入 八、企业文化与团队建设 九、应对危机的能力 前言 UT斯达康(UTStarcom&#…...

python如何多行注释
在Python中,多行注释通常有两种方式: 使用三个单引号()或三个双引号(""")来创建多行字符串,这可以被用来作为多行注释。这种方式在Python中实际上是创建了一个多行的字符串对象…...

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

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

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

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

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。 但是有的小伙伴会踩雷!导致定义的响应式丢失的问题。 reactive丢失响应式的情况1(直接赋值) 场景: 1.你定义了一个数据:let datareactive({name:"",age:"" }) 2.然后你…...

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

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

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

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

【系统架构核心服务设计】使用 Redis ZSET 实现排行榜服务
目录 一、排行榜的应用场景 二、排行榜技术的特点 三、使用Redis ZSET实现排行榜 3.1 引入依赖 3.2 配置Redis连接 3.3 创建实体类(可选) 3.4 编写 Redis 操作服务层 3.5 编写控制器层 3.6 测试 3.6.1 测试 addMovieScore 接口 3.6.2 测试 g…...

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