Android模拟手机QQ登录界面和主界面(含源码)

一、主要实现:

  • 手机QQ登录界面的设计
  • Intent的显式跳转和隐式跳转
  • EditText点击小图标清除输入框内容
  • EditText密码输入框中密码可见与不可见的切换
  • 使用Fragment实现底部导航栏切换界面
  • PopupMenu的简单使用

二、实验环境:

  • Android Studio 3.5.2
  • SDK版本:API 29
  • JDK 1.8

三、实现效果:

四、重点源码:

1.登录界面布局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_horizontal"
    android:orientation="vertical">

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="80dp"
        android:src="@drawable/smallqq" />
    <FrameLayout
        android:layout_width="350dp"
        android:layout_height="70dp"
        android:layout_marginTop="50dp" >

        <EditText
            android:id="@+id/qq_num"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@drawable/et_smallqq"
            android:hint="QQ号/手机号/邮箱"
            android:inputType="number"
            android:maxLines="1"
            android:textSize="20sp"
            android:gravity="center"/>

        <ImageView
            android:id="@+id/iv_et_num_delete"
            android:layout_width="25dp"
            android:layout_height="25dp"
            android:layout_gravity="right|center_vertical"
            android:layout_marginRight="20dp"
            android:background="@drawable/et_delete" />
    </FrameLayout>

    <FrameLayout
        android:layout_width="350dp"
        android:layout_height="70dp"
        android:layout_marginTop="20dp" >

        <EditText
            android:id="@+id/qq_pwd"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@drawable/et_smallqq"
            android:hint="输入密码"
            android:inputType="textPassword"
            android:maxLines="1"
            android:textSize="20sp"
            android:gravity="center"/>

        <ImageView
            android:id="@+id/iv_et_pwd_delete"
            android:layout_width="25dp"
            android:layout_height="25dp"
            android:layout_gravity="right|center_vertical"
            android:layout_marginRight="20dp"
            android:background="@drawable/et_delete" />
        <ImageView
            android:id="@+id/iv_et_pwd_see"
            android:layout_width="30dp"
            android:layout_height="20dp"
            android:layout_gravity="left|center_vertical"
            android:layout_marginLeft="20dp"
            android:src="@drawable/et_pwd_no" />
    </FrameLayout>

    <ImageView
        android:id="@+id/qq_login"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="80dp"
        android:src="@drawable/go_no" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:layout_marginTop="60dp"
        android:gravity="center"
        android:orientation="horizontal">

        <TextView
            android:id="@+id/qq_forgetpwd"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="忘记密码"
            android:textColor="@color/colorBlack" />

        <View
            android:layout_width="1dp"
            android:layout_height="10dp"
            android:layout_marginLeft="50dp"
            android:background="@color/colorBlackGery" />

        <TextView
            android:id="@+id/qq_register"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="50dp"
            android:text="用户注册"
            android:textColor="@color/colorBlack" />
    </LinearLayout>
</LinearLayout>

2.登录界面代码java

package com.asyyy.androidkaifa.smallqq;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.text.method.HideReturnsTransformationMethod;
import android.text.method.PasswordTransformationMethod;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import com.asyyy.androidkaifa.R;

public class SmallQQ_LoginActivity extends AppCompatActivity {

    private EditText et_qqnum, et_qqpwd;
    private ImageView iv_login, et_delete_num, et_delete_pwd, et_pwd_see;
    private TextView tv_forgetpwd, tv_register;
    private String qq_numtext, qq_pwdtext;
    private boolean pwdCanSee;

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

        findId();
        //QQ账号输入状态监听
        et_qqnum.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {

            }

            @Override
            public void afterTextChanged(Editable s) {
                qq_pwdtext = et_qqpwd.getText().toString().trim();
                qq_numtext = et_qqnum.getText().toString().trim();
                if(!TextUtils.isEmpty(qq_numtext) && !TextUtils.isEmpty(qq_pwdtext)){
                    //如果账号和密码都不为空,打开图片响应事件,并且更换图片
                    iv_login.setEnabled(true);
                    iv_login.setImageResource(R.drawable.go_yes);
                }else {
                    iv_login.setEnabled(false);
                    iv_login.setImageResource(R.drawable.go_no);
                }
            }
        });

        //QQ密码输入状态监听
        et_qqpwd.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {

            }

            @Override
            public void afterTextChanged(Editable s) {
                qq_pwdtext = et_qqpwd.getText().toString().trim();
                qq_numtext = et_qqnum.getText().toString().trim();
                if(!TextUtils.isEmpty(qq_numtext) && !TextUtils.isEmpty(qq_pwdtext)){
                    //如果账号和密码都不为空,打开图片响应事件,并且更换图片
                    iv_login.setEnabled(true);
                    iv_login.setImageResource(R.drawable.go_yes);
                }else {
                    iv_login.setEnabled(false);
                    iv_login.setImageResource(R.drawable.go_no);
                }
            }
        });
        //QQ密码输入焦点监听
        et_qqpwd.setOnFocusChangeListener((v, hasFocus) -> {
            if(hasFocus){
                et_pwd_see.setVisibility(View.VISIBLE);
            }else {
                et_pwd_see.setVisibility(View.INVISIBLE);
            }
        });

        //密码可见小图标
        pwdCanSee = false;//true密码可见,false密码不可见
        et_pwd_see.setOnClickListener(v -> {
            if(pwdCanSee){
                //设置不可见
                et_qqpwd.setTransformationMethod(PasswordTransformationMethod.getInstance());
                et_pwd_see.setImageResource(R.drawable.et_pwd_no);
                et_qqpwd.setSelection(et_qqpwd.getText().length());
                pwdCanSee = false;
            }else {
                //设置可见
                et_qqpwd.setTransformationMethod(HideReturnsTransformationMethod.getInstance());
                et_pwd_see.setImageResource(R.drawable.et_pwd_yes);
                et_qqpwd.setSelection(et_qqpwd.getText().length());
                pwdCanSee = true;
            }
        });

        //删除小图标
        EditTextUtils.clearButtonListener(et_qqnum, et_delete_num);
        EditTextUtils.clearButtonListener(et_qqpwd, et_delete_pwd);

        //登录
        //iv_login.setClickable(true);
        //setOnClickListener方法会默认把控件的setClickable设置为true。
        //设置login图片无事件响应
        iv_login.setEnabled(false);
        iv_login.setOnClickListener(v -> {
            qq_numtext = et_qqnum.getText().toString().trim();
            qq_pwdtext = et_qqpwd.getText().toString().trim();
            Toast.makeText(this,"登录成功!账号:" + qq_numtext + ",密码:" + qq_pwdtext,Toast.LENGTH_SHORT).show();
            Intent intent = new Intent(SmallQQ_LoginActivity.this, SmallQQ_MainChatActivity.class);
            startActivity(intent);
        });

        //忘记密码
        tv_forgetpwd.setOnClickListener(v -> {
            Intent intent = new Intent();
            intent.setAction("SmallQQ.error");
            startActivity(intent);
        });
        //用户注册
        tv_register.setOnClickListener(v -> startActivity(new Intent().setAction("SmallQQ.error")));
    }
    private void findId(){
        et_qqnum = findViewById(R.id.qq_num);
        et_qqpwd = findViewById(R.id.qq_pwd);
        iv_login = findViewById(R.id.qq_login);
        tv_forgetpwd = findViewById(R.id.qq_forgetpwd);
        tv_register = findViewById(R.id.qq_register);
        et_delete_num = findViewById(R.id.iv_et_num_delete);
        et_delete_pwd = findViewById(R.id.iv_et_pwd_delete);
        et_pwd_see = findViewById(R.id.iv_et_pwd_see);
    }
}

3.显示主界面布局xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    >
    <RelativeLayout
        android:id="@+id/top_bar"
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:background="@color/colorSmallQQ"
        >
        <ImageView
            android:id="@+id/user_photo"
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:layout_marginLeft="20dp"
            android:layout_centerVertical="true"
            android:src="@drawable/photo"
            />
        <TextView
            android:id="@+id/user_title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:textSize="24sp"
            android:textColor="@color/colorWhite"
            android:textStyle="bold"
            android:text="消息"
            />
        <ImageView
            android:id="@+id/menu_add"
            android:layout_width="24dp"
            android:layout_height="24dp"
            android:layout_marginRight="20dp"
            android:layout_alignParentRight="true"
            android:layout_centerVertical="true"
            android:src="@drawable/add"
            />
    </RelativeLayout>
    <FrameLayout
        android:id="@+id/fragment_content"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@id/top_bar"
        android:layout_above="@id/bottom_bar">

    </FrameLayout>
    <LinearLayout
        android:id="@+id/bottom_bar"
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:layout_alignParentBottom="true"
        android:orientation="horizontal">
        <TextView
            android:id="@+id/tvbar_user"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:drawableTop="@drawable/bar_news"
            android:drawablePadding="3dp"
            android:gravity="center"
            android:textColor="@drawable/bar_text"
            android:text="消息"/>
        <TextView
            android:id="@+id/tvbar_friend"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:drawableTop="@drawable/bar_friend"
            android:drawablePadding="3dp"
            android:gravity="center"
            android:textColor="@drawable/bar_text"
            android:text="联系人"/>
        <TextView
            android:id="@+id/tvbar_dongtai"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:drawableTop="@drawable/bar_dongtai"
            android:drawablePadding="3dp"
            android:gravity="center"
            android:textColor="@drawable/bar_text"
            android:text="动态"/>
    </LinearLayout>
</RelativeLayout>

4.显示主界面代码java

package com.asyyy.androidkaifa.smallqq;

import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.view.menu.MenuPopupHelper;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;

import android.os.Bundle;
import android.view.MenuItem;
import android.view.View;
import android.widget.ImageView;
import android.widget.PopupMenu;
import android.widget.TextView;
import android.widget.Toast;

import com.asyyy.androidkaifa.R;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class SmallQQ_MainChatActivity extends AppCompatActivity implements View.OnClickListener {

    private TextView user_title, bar_news, bar_friend, bar_dongtai;
    private ImageView menu_add;

    private NewsFragment newsFragment;
    private FriendFragment friendFragment;
    private DongtaiFragment dongtaiFragment;
    private FragmentManager fManager;

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

        user_title = findViewById(R.id.user_title);
        bar_news = findViewById(R.id.tvbar_user);
        bar_friend = findViewById(R.id.tvbar_friend);
        bar_dongtai = findViewById(R.id.tvbar_dongtai);
        menu_add  = findViewById(R.id.menu_add);

        bar_news.setOnClickListener(this);
        bar_friend.setOnClickListener(this);
        bar_dongtai.setOnClickListener(this);

        fManager = getSupportFragmentManager();

        bar_news.performClick();//模拟一次点击,既进去后选择消息界面

        menu_add.setOnClickListener(v -> {
            PopupMenu popupMenu = new PopupMenu(SmallQQ_MainChatActivity.this, menu_add);
            popupMenu.getMenuInflater().inflate(R.menu.menu_add,popupMenu.getMenu());
            popupMenu.setOnMenuItemClickListener(item -> {
                String str = "";
                switch (item.getItemId()){
                    case R.id.menu_add1:
                        str = item.getTitle() + "";
                        break;
                    case R.id.menu_add2:
                        str = item.getTitle() + "";
                        break;
                    case R.id.menu_add3:
                        str = item.getTitle() + "";
                        break;
                    case R.id.menu_add4:
                        str = item.getTitle() + "";
                        break;
                    case R.id.menu_add5:
                        str = item.getTitle() + "";
                        break;
                    case R.id.menu_add6:
                        str = item.getTitle() + "";
                        break;
                }
                Toast.makeText(SmallQQ_MainChatActivity.this,"你点击了 " + str, Toast.LENGTH_SHORT).show();
                return true;
            });
            popupMenu.show();
        });

    }

    //重置所有文本的选中状态
    private void setSelected(){
        bar_news.setSelected(false);
        bar_friend.setSelected(false);
        bar_dongtai.setSelected(false);
    }

    //隐藏所有Fragment
    private void hideAllFragment(FragmentTransaction transaction){
        if(newsFragment != null) transaction.hide(newsFragment);
        if(friendFragment != null) transaction.hide(friendFragment);
        if(dongtaiFragment != null) transaction.hide(dongtaiFragment);
    }

    @Override
    public void onClick(View v) {
        //FragmentTransaction只能使用一次
        //每次使用都要调用FragmentManager的beginTransaction()方法获得FragmentTransaction事务对象
        FragmentTransaction transaction = fManager.beginTransaction();
        hideAllFragment(transaction);
        switch (v.getId()){
            case R.id.tvbar_user:
                setSelected();
                bar_news.setSelected(true);
                user_title.setText("消息");
                if(newsFragment == null){
                    newsFragment = new NewsFragment();
                    transaction.add(R.id.fragment_content, newsFragment);
                }else {
                    transaction.show(newsFragment);
                }
                break;
            case R.id.tvbar_friend:
                setSelected();
                bar_friend.setSelected(true);
                user_title.setText("联系人");
                if(friendFragment == null){
                    friendFragment = new FriendFragment();
                    transaction.add(R.id.fragment_content, friendFragment);
                }else {
                    transaction.show(friendFragment);
                }
                break;
            case R.id.tvbar_dongtai:
                setSelected();
                bar_dongtai.setSelected(true);
                user_title.setText("动态");
                if(dongtaiFragment == null){
                    dongtaiFragment = new DongtaiFragment();
                    transaction.add(R.id.fragment_content, dongtaiFragment);
                }else {
                    transaction.show(dongtaiFragment);
                }
                break;
        }
        //把newsFragment添加到Activity中的指定位置,最后调用commit()或者commitAllowingStateLoss()
        transaction.commitAllowingStateLoss();
    }
}

五、源码下载:

积分下载(包含源码,用到的各种图片)

注:当初上传的时候设置的是0积分,但是积分会自动慢慢加,当初的文件我现在也不太好找了,不过重要的代码也粘贴出来了

https://download.csdn.net/download/qq_40907345/12377480

  • 40
    点赞
  • 229
    收藏
    觉得还不错? 一键收藏
  • 18
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 18
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值