Android入门项目(校园软件)

写在前面

该项目是一个Android项目,非常适合新手,基本运用了所有的常见组件和布局,小说部分还用到了java爬虫技术,无论是学习还是装x都十分合适。还有完整的文档帮你理解代码,从欢迎界面入手循序渐进的完成整个项目的学习。
适用范围:
1.用于完成学校Android作业的朋友。
2.需要一个Android项目来学习技术的朋友。
3.想要写一个社区之类软件但是自己不想写界面的朋友,可以再此之上继续自己添加内容。

粗略把结构分成了这样
仓库地址

目录结构


首先自定义一个MyApplication继承Application,完成一个获取context的方法,方便后面在需要用的地方可以直接使用MyApplication.getContext()方法直接获取context。(虽然我每次都忘了用)

有的地方不建议将Context定义成静态的,具体原因我还没有深入了解,这个方法是真的很方便。

public class MyApplication extends Application {
    private static Context context;
    @Override
    public void onCreate() {
        super.onCreate();
        context = getApplicationContext();
    }
    public  static Context getContext()
    {
        return context;
    }
}

再开始第一个页面时,在配置文件中values中的style里把actionBar改为NoActionBar。设置为隐藏actionbar。

欢迎界面

设置在应用开始后先进入一个欢迎页面在进入main页面

public class WelcomeActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_weclome);
        Timer timer=new Timer();
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                toMain();
            }
        },2000);
    }

    private void toMain() {
        startActivity(new Intent(WelcomeActivity.this,MainActivity.class));
        finish();
    }
}
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:drawableTop="@mipmap/iswust"
        android:gravity="center"
        android:text="爱西科生活"
        android:textColor="#000"
        android:textStyle="bold"
        android:textSize="30sp"
        />

</FrameLayout>

这样欢迎页面就算完成。

登录界面

然后就是开始第一个界面吧,先是登录界面的布局。
activity_main.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:fitsSystemWindows="true"
    android:orientation="vertical"
    >
    <ImageView
        android:src="@mipmap/iswust"
        android:layout_gravity="center_horizontal"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>
    <EditText
        android:padding="8dp"
        android:layout_marginTop="30dp"
        android:layout_width="match_parent"
        android:layout_marginLeft="30dp"
        android:layout_marginRight="30dp"
        android:layout_height="wrap_content"
        android:hint="手机号"
        android:drawableLeft="@mipmap/ic_login_account_icon"
        android:layout_gravity="center_horizontal"
        android:background="@drawable/bac_1"/>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:layout_marginTop="15dp">
        <EditText
            android:layout_width="0dp"
            android:background="@drawable/bac_1"
            android:padding="8dp"
            android:layout_height="wrap_content"
            android:drawableLeft="@mipmap/ic_login_code_icon"
            android:layout_weight="3"
            android:layout_marginLeft="30dp"
            android:hint="验证码"
            />
        <Button
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="50dp"
            android:text="获取验证码"
            android:layout_marginRight="30dp"
            android:textColor="@android:color/white"
            android:background="@drawable/bac_2"
            android:layout_marginLeft="15dp"/>
    </LinearLayout>
    <Button
        android:id="@+id/btn_login1"
        android:layout_width="300dp"
        android:layout_height="50dp"
        android:layout_marginTop="20dp"
        android:textSize="20sp"
        android:textColor="@android:color/white"
        android:background="@drawable/bac_2"
        android:layout_gravity="center_horizontal"
        android:text="登录/注册"/>
    <TextView
        android:id="@+id/in"
        android:layout_marginLeft="50dp"
        android:layout_marginTop="10dp"
        android:padding="8dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="使用旧版登录接口"
        android:clickable="true"
        android:textColor="#5382D2"/>

    <TextView
        android:layout_gravity="center_horizontal"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="80dp"
        android:text="——————第三方登录——————"/>
    <LinearLayout
        android:layout_marginTop="20dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <TextView
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:drawableTop="@mipmap/wechat"
            android:gravity="center"
            android:text="微信" />

        <TextView
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="wrap_content"
            android:drawableTop="@mipmap/qq"
            android:gravity="center"
            android:text="QQ"/>
    </LinearLayout>
    <LinearLayout
        android:layout_marginTop="20dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:gravity="center"
        >
        <TextView
            android:text="登录即代表同意"
            android:layout_height="wrap_content"
            android:layout_width="wrap_content" />
        <TextView
            android:layout_height="wrap_content"
            android:layout_width="wrap_content"
            android:text="《服务协议》"
            android:textColor="#7D9BD7"/>
    </LinearLayout>

</LinearLayout>

用到的图片也是在网络中获取的,有的是学长发给我的。所以大家可以随意添加。
对按钮的自定义修饰也是因人而异开心就好。
虽然已经有很多人提过,但还是推荐一下这个图标网站 -->点这里https://www.iconfont.cn/

当时为了方便,这里并没有把用到的文本在strings中定义,严格来讲这是不规范的,大家看看就好。
效果如图


出于模仿的目的,很多只实现了界面,像qq,微信这些功还没办法实现,点击按钮会产生一些效果,真正的入口也就在使用旧版登录接口那里。

public class MainActivity extends AppCompatActivity {
    private TextView textView;
    private Button button;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        button=findViewById(R.id.btn_login1);
        textView=findViewById(R.id.in);
        textView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent=new Intent(MainActivity.this,LoginActivity.class);
                startActivity(intent);
            }
        });
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(MyApplication.getContext(),"请使用旧版登录接口",Toast.LENGTH_SHORT).show();
            }
        });
    }

}

为了简单,可能还是不够规范。
当时为了熟悉布局就写了很多这种页面练手。
接下来就跳转到旧版的登录页面了和上面的界面大同小异。同理如下
activity_login

<?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:fitsSystemWindows="true"
    android:background="@drawable/background_1"
    android:orientation="vertical"
    >
    <ImageView
        android:src="@mipmap/iswust"
        android:layout_gravity="center_horizontal"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="爱西科生活"
        android:textSize="35sp"
        android:textStyle="bold"
        android:textColor="#000"
        android:layout_gravity="center"
        />
    <EditText
        android:id="@+id/username"
        android:padding="8dp"
        android:layout_margin="30dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="学号/工号"
        android:drawableLeft="@mipmap/ic_login_account_icon"
        android:background="@drawable/bac_1"/>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
>
        <EditText
            android:id="@+id/password"
            android:layout_width="match_parent"
            android:padding="8dp"
            android:background="@drawable/bac_1"
            android:layout_marginLeft="30dp"
            android:layout_marginRight="30dp"
            android:layout_height="wrap_content"
            android:drawableLeft="@mipmap/ic_login_code_icon"
            android:inputType="textPassword"
            android:hint="i西科密码"
            />
    </LinearLayout>
    <Button
        android:id="@+id/btn_login"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:layout_marginRight="30dp"
        android:layout_marginLeft="30dp"
        android:textSize="20sp"
        android:textColor="@android:color/white"
        android:background="@drawable/bac_2"
        android:layout_gravity="center_horizontal"
        android:text="登录"/>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
        <TextView
            android:id="@+id/tv_register"
            android:layout_marginTop="10dp"
            android:padding="8dp"
            android:layout_width="0dp"
            android:layout_weight="1"
            android:textStyle="bold"
            android:gravity="center"
            android:layout_height="wrap_content"
            android:text="用户注册"
            android:clickable="true"
            android:textColor="#5382D2"/>
        <TextView
            android:layout_marginTop="10dp"
            android:padding="8dp"
            android:layout_width="0dp"
            android:textStyle="bold"
            android:gravity="center"
            android:layout_weight="1"
            android:layout_height="wrap_content"
            android:text="忘记密码"
            android:textColor="#5382D2"/>
    </LinearLayout>
    <TextView
        android:layout_gravity="center_horizontal"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="80dp"
        android:textStyle="bold"
        android:textColor="#ffff00"
        android:text="——————第三方登录——————"/>

    <LinearLayout
        android:layout_marginTop="20dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <TextView
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:textStyle="bold"
            android:drawableTop="@mipmap/wechat"
            android:gravity="center"
            android:text="微信" />

        <TextView
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:drawableTop="@mipmap/qq"
            android:gravity="center"
            android:textStyle="bold"
            android:text="QQ"/>
    </LinearLayout>
    <LinearLayout
        android:layout_marginTop="20dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:orientation="horizontal">

        <TextView
            android:text="登录即代表同意"
            android:textColor="#ffff00"
            android:textStyle="bold"
            android:layout_height="wrap_content"
            android:layout_width="wrap_content" />
        <TextView
            android:layout_height="wrap_content"
            android:layout_width="wrap_content"
            android:textStyle="bold"
            android:text="《服务协议》"
            android:textColor="#ffff00"
            />
    </LinearLayout>

</LinearLayout>

图片资源文件任意。

public class LoginActivity extends AppCompatActivity {
    private EditText username;
    private EditText password;
    private Button login;
    private TextView register;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);
        findViews();
    }
    private void findViews() {
        username=(EditText) findViewById(R.id.username);
        password=(EditText) findViewById(R.id.password);
        login=(Button) findViewById(R.id.btn_login);
        register=(TextView) findViewById(R.id.tv_register);

        login.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String name=username.getText().toString();
                System.out.println(name);
                String pass=password.getText().toString();
                System.out.println(pass);
                UserService userService=new UserService(LoginActivity.this);
                boolean flag=userService.login(name, pass);
                if(flag){
                    Toast.makeText(LoginActivity.this, "登录成功", Toast.LENGTH_LONG).show();
                    Intent intent = new Intent(MyApplication.getContext(), MainpageActivity.class);
                    startActivity(intent);
                    finish();
                }else{
                    Toast.makeText(MyApplication.getContext(), "登录失败", Toast.LENGTH_LONG).show();
                }
            }
        });
                register.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                Intent intent=new Intent(LoginActivity.this,RegisterActivity.class);
                startActivity(intent);
            }
        });
    }
}

为了能够登录进去,就需要实现注册功能,为了实现注册功能,这里我采用sqllite。

注册页面

在这里插入图片描述
方法大同小异,不在重复。
接下来就是实现注册功能。
使用自带的Sqllite数据库。

Sqllite数据库

public class User {
    private int id;
    private String username;
    private String password;
    public User() {
        super();
    }
    public User(String username, String password) {
        super();
        this.username = username;
        this.password = password;
    }
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    @Override
    public String toString() {
        return "User [id=" + id + ", username=" + username + ", password="
                + password + "]";
    }

}


public class DatabaseHelper extends SQLiteOpenHelper {
    static String name="user.db";
    static int dbVersion=1;
    //创建
    public DatabaseHelper(Context context) {
        super(context, name, null, dbVersion);
    }
    public void onCreate(SQLiteDatabase db)  {
        String sql="create table user(id integer primary key autoincrement,username varchar(20),password varchar(20))";
        db.execSQL(sql);
    }
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    }

}

public class UserService {
    private DatabaseHelper dbHelper;
    public UserService(Context context){
        dbHelper=new DatabaseHelper(context);
    }
    public boolean login(String username,String password){
        SQLiteDatabase sdb=dbHelper.getReadableDatabase();
        String sql="select * from user where username=? and password=?";
        Cursor cursor=sdb.rawQuery(sql, new String[]{username,password});
        if(cursor.moveToFirst()==true){
            cursor.close();
            return true;
        }
        return false;
    }
    //添加
    public boolean register(User user){
        SQLiteDatabase sdb=dbHelper.getReadableDatabase();
        String sql="insert into user(username,password) values(?,?)";
        Object obj[]={user.getUsername(),user.getPassword()};
        sdb.execSQL(sql, obj);
        return true;
    }
}


public class RegisterActivity extends AppCompatActivity {
    EditText username;
    EditText password;
    Button register;
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_register);
        findViews();
        register.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                String name=username.getText().toString().trim();//去掉两端的空格
                String pass=password.getText().toString().trim();
                UserService userService=new UserService(RegisterActivity.this);
                User user=new User();
                user.setUsername(name);
                user.setPassword(pass);
                userService.register(user);
                Toast.makeText(RegisterActivity.this, "注册成功", Toast.LENGTH_LONG).show();
                Intent intent = new Intent(RegisterActivity.this,LoginActivity.class);
                startActivity(intent);
                finish();
            }
        });
    }
    private void findViews() {
        username=(EditText) findViewById(R.id.usernameRegister);
        password=(EditText) findViewById(R.id.passwordRegister);
        register=(Button) findViewById(R.id.Register);
    }
}


主界面

注册功能实现成功之后,就可以点击登录按钮成功进入主界面了。

主界面采用的是Activity+Fragment实现的
创建主界面Activity

public class MainpageActivity extends AppCompatActivity implements RadioGroup.OnCheckedChangeListener,
        ViewPager.OnPageChangeListener {
    private RadioGroup btn_group;
    private RadioButton btn_1;
    private RadioButton btn_2;
    private RadioButton btn_3;
    private ViewPager vpager;

    private MyFragmentPagerAdapter mAdapter;

    public static final int PAGE_ONE = 0;
    public static final int PAGE_TWO = 1;
    public static final int PAGE_THREE = 2;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_mainpage);
    mAdapter = new MyFragmentPagerAdapter(getSupportFragmentManager());
    bindViews();
    btn_1.setChecked(true);
}
    private void bindViews() {
        btn_group = (RadioGroup) findViewById(R.id.btn_group);
        btn_1 = (RadioButton) findViewById(R.id.btn_1);
        btn_2 = (RadioButton) findViewById(R.id.btn_2);
        btn_3 = (RadioButton) findViewById(R.id.btn_3);
        btn_group.setOnCheckedChangeListener(this);

        vpager = (ViewPager) findViewById(R.id.viewpager);
        vpager.setAdapter(mAdapter);
        vpager.setCurrentItem(0);
        vpager.addOnPageChangeListener(this);
    }
    @Override
    public void onCheckedChanged(RadioGroup group, int checkedId) {
        switch (checkedId) {
            case R.id.btn_1:
                vpager.setCurrentItem(PAGE_ONE);
                break;
            case R.id.btn_2:
                vpager.setCurrentItem(PAGE_TWO);
                break;
            case R.id.btn_3:
                vpager.setCurrentItem(PAGE_THREE);
                break;
        }
    }


    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
    }

    @Override
    public void onPageSelected(int position) {
    }

    @Override
    public void onPageScrollStateChanged(int state) {
        //state的状态有三个,0表示什么都没做,1正在滑动,2滑动完毕
        if (state == 2) {
            switch (vpager.getCurrentItem()) {
                case PAGE_ONE:
                    btn_1.setChecked(true);
                    break;
                case PAGE_TWO:
                    btn_2.setChecked(true);
                    break;
                case PAGE_THREE:
                    btn_3.setChecked(true);
                    break;
            }
        }
    }
}

布局为

<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout
    android:layout_height="match_parent"
    android:layout_width="match_parent"
    android:fitsSystemWindows="true"
    xmlns:android="http://schemas.android.com/apk/res/android">
    <RelativeLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".Activities.MainpageActivity">
        <LinearLayout
            android:id="@+id/re1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="#4286F5"
            android:fitsSystemWindows="true"
            android:orientation="horizontal">

            <TextView
                android:id="@+id/title"
                android:layout_width="0dp"
                android:layout_height="40dp"
                android:layout_margin="10dp"
                android:layout_weight="6"
                android:drawableLeft="@mipmap/iceman"
                android:drawablePadding="20dp"
                android:text="今日"
                android:textColor="#FFFFFF"
                android:textSize="25sp" />
        </LinearLayout>
        <RadioGroup
            android:id="@+id/btn_group"
            android:layout_width="match_parent"
            android:layout_height="56dp"
            android:layout_alignParentBottom="true"
            android:background="#FFFFFF"
            android:orientation="horizontal">
            <RadioButton
                android:id="@+id/btn_1"
                android:text="今日"
                android:textColor="#0997F7"
                android:drawableTop="@drawable/btn_1"
                android:button="@null"
                android:layout_height="wrap_content"
                android:gravity="center"
                android:layout_weight="1"
                android:layout_width="0dp"
                />

            <RadioButton
                android:id="@+id/btn_2"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:button="@null"
                android:drawableTop="@drawable/btn_2"
                android:gravity="center"
                android:text="音乐"
                android:layout_weight="1"
                android:textColor="#0997F7" />

            <RadioButton
                android:id="@+id/btn_3"
                android:text="网络"
                android:textColor="#0997F7"
                android:drawableTop="@drawable/btn_3"
                android:button="@null"
                android:layout_height="wrap_content"
                android:gravity="center"
                android:layout_width="0dp"
                android:layout_weight="1" />
        </RadioGroup>

        <View
            android:id="@+id/line"
            android:layout_width="match_parent"
            android:layout_height="2px"
            android:layout_above="@id/btn_group"
            android:background="#0997F7" />

        <androidx.viewpager.widget.ViewPager
            android:id="@+id/viewpager"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_above="@id/line"
            android:layout_below="@+id/re1"
            />
    </RelativeLayout>

    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#fff"
        android:textSize="30sp"
        android:layout_gravity="left"
        android:text="This is Test"
        />
</androidx.drawerlayout.widget.DrawerLayout>

viewPager的使用

这里采用了viewPager实现三个子页面。
要实现viewPager就需要单独来写一个适配器了。

public class MyFragmentPagerAdapter extends FragmentPagerAdapter {
    private final int PAGER_COUNT = 3;
    private MyFragment1 myFragment1 ;
    private MyFragment2 myFragment2 ;
    private MyFragment3 myFragment3 ;

    public MyFragmentPagerAdapter(FragmentManager fm) {
        super(fm);
        myFragment1 = new MyFragment1();
        myFragment2 = new MyFragment2();
        myFragment3 = new MyFragment3();
    }
    @Override
    public int getCount() {
        return PAGER_COUNT;
    }

    @Override
    public Object instantiateItem(ViewGroup vg, int position) {
        return super.instantiateItem(vg, position);
    }

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        super.destroyItem(container, position, object);
    }

    @Override
    public Fragment getItem(int position) {
        Fragment fragment = null;
        switch (position) {
            case MainpageActivity.PAGE_ONE:
                fragment = myFragment1;
                break;
            case MainpageActivity.PAGE_TWO:
                fragment = myFragment2;
                break;
            case MainpageActivity.PAGE_THREE:
                fragment = myFragment3;
                break;
        }
        return fragment;
    }
}

所用到的几个fragment,可以先简单的加一些内容先确保正确性,等适配器写好之后就可以简单的主界面也就完成了。
另外写viewpager的适配器除了可以继承FragmentPagerAdapter外,还可以继承PagerAdapter重写四个方法也能达到效果也是相当简单。

在这里插入图片描述
接下来我们就可以往fragment中添加内容充实一下了。

第一个碎片页面

在第一个碎片中,我在最上方又加了一个viewpager,为了实现一个轮播图类似于广告的效果。然后在下方随意设置几个按钮,在设置按钮时,按理来说运用recycleview或者gridView会更好一些,但当时为了速度,就偷懒直接采用布局排列了。

<?xml version="1.0" encoding="utf-8"?>
<ScrollView
    android:layout_height="match_parent"
    android:layout_width="match_parent"
    xmlns:android="http://schemas.android.com/apk/res/android">
    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
        <androidx.viewpager.widget.ViewPager
            android:id="@+id/advpager"
            android:layout_width="match_parent"
            android:layout_height="300dp"
            />
        <LinearLayout
            android:id="@+id/ll_btn"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">
            <Button
                android:id="@+id/btn_a"
                android:layout_width="0dp"
                android:layout_weight="1"
                android:layout_height="wrap_content"
                android:drawableTop="@mipmap/dog"
                style="?android:attr/borderlessButtonStyle"
                android:text="按钮a" />

            <Button
                android:id="@+id/btn_b"
                android:layout_width="0dp"
                android:layout_weight="1"
                android:layout_height="wrap_content"
                android:drawableTop="@mipmap/tiger"
                style="?android:attr/borderlessButtonStyle"
                android:text="按钮b" />

            <Button
                android:id="@+id/btn_c"
                android:layout_width="0dp"
                android:layout_weight="1"
                android:layout_height="wrap_content"
                android:drawableTop="@mipmap/changjinglu"

                style="?android:attr/borderlessButtonStyle"
                android:text="按钮c" />

            <Button
                android:id="@+id/btn_d"
                android:layout_width="0dp"
                android:layout_weight="1"
                android:layout_height="wrap_content"
                android:drawableTop="@mipmap/songshu"

                style="?android:attr/borderlessButtonStyle"
                android:text="按钮d" />
        </LinearLayout>
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">
            <Button
                android:id="@+id/btn_e"
                android:layout_width="0dp"
                android:layout_weight="1"
                android:layout_height="wrap_content"
                android:drawableTop="@mipmap/horse"

                style="?android:attr/borderlessButtonStyle"
                android:text="按钮e" />
            <Button
                android:id="@+id/btn_f"
                android:layout_width="0dp"
                android:layout_weight="1"
                android:layout_height="wrap_content"
                android:drawableTop="@mipmap/lion"
                style="?android:attr/borderlessButtonStyle"
                android:text="按钮f" />
            <Button
                android:id="@+id/btn_g"
                android:layout_width="0dp"
                android:layout_weight="1"
                android:layout_height="wrap_content"
                android:drawableTop="@mipmap/panda"
                style="?android:attr/borderlessButtonStyle"
                android:text="按钮g" />

            <CheckBox
                android:id="@+id/btn_h"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:drawableTop="@drawable/more"
                android:button="@null"
                android:gravity="center"
                android:text="更多" />

        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            >
            <Button
                android:id="@+id/btn_text"
                style="?android:attr/borderlessButtonStyle"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:drawableTop="@mipmap/text"
                android:text="西科小说" />
            <Button
                android:id="@+id/btn_movie"
                android:layout_width="0dp"
                android:layout_weight="1"
                android:layout_height="wrap_content"
                android:drawableTop="@mipmap/movie"
                style="?android:attr/borderlessButtonStyle"
                android:text="西科电影" />
        </LinearLayout>

    </LinearLayout>
</ScrollView>

轮播图

所用到的图标大家还是随便用自己喜欢的就行。
然后就又是写轮播图的viewpager适配器


public class AdAdapter extends FragmentPagerAdapter {
private AdFragment1 adfragment1;
private AdFragment2 adfragment2;
private AdFragment3 adfragment3;
    public AdAdapter(FragmentManager fm) {
        super(fm);
        adfragment1=new AdFragment1();
        adfragment2=new AdFragment2();
        adfragment3=new AdFragment3();
    }



    @Override
    public Fragment getItem(int position) {
        Fragment fragment = null;
        switch (position) {
            case MainpageActivity.PAGE_ONE:
                fragment = adfragment1;
                break;
            case MainpageActivity.PAGE_TWO:
                fragment = adfragment2;
                break;
            case MainpageActivity.PAGE_THREE:
                fragment = adfragment3;
                break;
        }
        return fragment;
    }

    @Override
    public Object instantiateItem(ViewGroup vg, int position) {
        return super.instantiateItem(vg, position);
    }

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        super.destroyItem(container, position, object);
    }
    @Override
    public int getCount() {
        return 3;
    }

}

与之前的大同小异,其实继承pagerview,传入几个view直接显示会更方便与直观一些,我运用fragment的原因是为了当时不熟悉继承了FragmentAdapter该怎么用,为了加深印象就又使用了一遍。

第一个碎片页面

接着就继续实现了第一个碎片页面

public class MyFragment1 extends Fragment {
    View view;
    ViewPager advpager = null;
    Button buttona,buttonb,buttonc,buttond,buttone,buttonf,buttong,buttontext,button_movie;
    CheckBox buttonh;
    boolean isVisible =true;
    @Override
    public View onCreateView(final LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        view = inflater.inflate(R.layout.fg_1, container, false);
        AdAdapter adAdapter = new AdAdapter(getChildFragmentManager());
        advpager = view.findViewById(R.id.advpager);
        advpager.setAdapter(adAdapter);
        buttona=view.findViewById(R.id.btn_a);
        buttonb=view.findViewById(R.id.btn_b);
        buttonc=view.findViewById(R.id.btn_c);
        buttond=view.findViewById(R.id.btn_d);
        buttone=view.findViewById(R.id.btn_e);
        buttonf=view.findViewById(R.id.btn_f);
        buttong=view.findViewById(R.id.btn_g);
        buttonh=view.findViewById(R.id.btn_h);
        buttontext=view.findViewById(R.id.btn_text);
        button_movie=view.findViewById(R.id.btn_movie);
        buttontext.setVisibility(View.INVISIBLE);
        button_movie.setVisibility(View.INVISIBLE);
        buttontext.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent =new Intent(getContext(), BookActivity.class);
                startActivity(intent);
                Toast.makeText(getContext(),"请选择章节",Toast.LENGTH_SHORT).show();

            }
        });
        button_movie.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent=new Intent(getContext(), MovieActivity.class);
                startActivity(intent);
            }
        });
        buttonh.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(isVisible)
                {
                    buttontext.setVisibility(View.VISIBLE);
                    button_movie.setVisibility(View.VISIBLE);
                    isVisible=false;
                }
                else
                {
                    buttontext.setVisibility(View.INVISIBLE);
                    button_movie.setVisibility(View.INVISIBLE);
                    isVisible=true;
                }
            }
        });
        return view;
    }

    @Override
    public void onResume() {
        super.onResume();
        mHandler.sendEmptyMessageDelayed(1,3000);
    }
    @SuppressLint("HandlerLeak")
    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case 1:
                    int count = 3;
                    int currentItem=advpager.getCurrentItem();
                    int now=(currentItem+1)%count;
                    advpager.setCurrentItem(now,true);
                    this.sendEmptyMessageDelayed(1,3000);
            }
        }
    };
}

在这里插入图片描述
为了实现轮播图的效果,用到Handler来接受从onResume发出的消息更新ui,每三秒更新一次。Onresume()是活动准备好和用户交互的时候调用,只需重写用来发消息即可。

在第一个界面中的更多按钮中,设计了一个小说按钮,点击可以进入小说界面。
小说界面同样简单,简单设置即可。

<?xml version="1.0" encoding="utf-8"?>

<androidx.constraintlayout.widget.ConstraintLayout xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <RelativeLayout
        android:id="@+id/line_title"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#4286F5"
        android:fitsSystemWindows="true"
        tools:ignore="MissingConstraints">
        <TextView
            android:id="@+id/title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:text="西科小说"
            android:layout_centerInParent="true"
            android:textColor="#fff"
            android:textSize="30sp"
            tools:ignore="MissingConstraints" />
        <Button
            android:id="@+id/title_btn"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="#4286F5"
            android:text="目录"
            android:textSize="20sp"
            android:textColor="#fff"
            style="?android:attr/borderlessButtonStyle"
            tools:ignore="MissingConstraints" />
    </RelativeLayout>

    <ScrollView
        android:id="@+id/scr_text"
        app:layout_constraintTop_toBottomOf="@id/line_title"
        app:layout_constraintBottom_toTopOf="@+id/re_1"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:fillViewport="true"
        tools:ignore="MissingConstraints" >
        <TextView
            android:id="@+id/text"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:scrollbars="vertical"
            android:fadeScrollbars="false"
            tools:ignore="MissingConstraints,NotSibling"
            />
    </ScrollView>

    <RelativeLayout
        android:id="@+id/re_1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#4286F5"
        app:layout_constraintBottom_toBottomOf="parent"
        tools:ignore="NotSibling"
        tools:layout_editor_absoluteX="0dp">

        <Button
            android:id="@+id/last_zhang"
            style="?android:attr/borderlessButtonStyle"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:clickable="true"

            android:text="上一章"
            android:textColor="#fff"
            android:textSize="25sp" />

        <Button
            android:id="@+id/next_zhang"
            style="?android:attr/borderlessButtonStyle"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:clickable="true"
            android:text="下一章>"
            android:textColor="#fff"
            android:textSize="25sp" />
    </RelativeLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

爬取小说内容

在bookactivity中采用okhttp来访问网络并采用异步的方式返回结果。在这其中运用Jsoup来爬取小说网站上文本内容(仅学习使用,未用作任何商业用途)最后运用handler来更新ui。

public class BookActivity extends AppCompatActivity {
    TextView mainText;
    Button title_btn;
    Button textView1,textView2;
    int flag;
    ScrollView scrollView;
    Handler handler =new Handler(Looper.getMainLooper())
    {
        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);
            switch (msg.what)
            {
                case 1:mainText.setText((String)msg.obj);
                    break;
            }
        }
    };
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_book);
        mainText = findViewById(R.id.text);
        title_btn = findViewById(R.id.title_btn);
        textView1=findViewById(R.id.last_zhang);
        textView2=findViewById(R.id.next_zhang);
        scrollView=findViewById(R.id.scr_text);
        mainText.setMovementMethod(ScrollingMovementMethod.getInstance());

//        sendRequest();
        textView1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                switch (flag){
                    case 1:Toast.makeText(BookActivity.this,"没有上一章啦!",Toast.LENGTH_SHORT).show();
                    break;
                    case 2:scrollView.smoothScrollTo(0,0);
                        sendRequest("http://book.zongheng.com/chapter/1028707/61764491.html");
                    flag--;
                    break;
                    case 3:scrollView.smoothScrollTo(0,0);
                        sendRequest("http://book.zongheng.com/chapter/1028707/61764498.html");
                    flag--;
                    break;
                }
            }
        });
        textView2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                switch (flag){

                    case 1:
                        scrollView.smoothScrollTo(0,0);
                        sendRequest("http://book.zongheng.com/chapter/1028707/61764498.html");
                        flag++;
                        break;
                    case 2:
                        scrollView.smoothScrollTo(0,0);
                        sendRequest("http://book.zongheng.com/chapter/1028707/61764524.html");
                    flag++;
                        break;
                    case 3:
                        Toast.makeText(BookActivity.this,"没有下一章啦!",Toast.LENGTH_SHORT).show();
                        break;
                }
            }
        });
        title_btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                PopupMenu popupMenu =new PopupMenu(BookActivity.this,title_btn);
                popupMenu.getMenuInflater().inflate(R.menu.title_menu,popupMenu.getMenu());
                popupMenu.show();
                popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
                    @Override
                    public boolean onMenuItemClick(MenuItem item) {
                        switch (item.getItemId())
                        {
                            case R.id.text_1:
                                flag=1;
                                scrollView.smoothScrollTo(0,0);
                                sendRequest("http://book.zongheng.com/chapter/1028707/61764491.html");
                                Toast.makeText(BookActivity.this,"第一章",Toast.LENGTH_SHORT).show();
                                break;
                            case R.id.text_2:
                                flag=2;
                                scrollView.smoothScrollTo(0,0);
                                sendRequest("http://book.zongheng.com/chapter/1028707/61764498.html");
                                Toast.makeText(BookActivity.this,"第二章",Toast.LENGTH_SHORT).show();
                                break;
                            case R.id.text_3:
                                flag=3;
                                scrollView.smoothScrollTo(0,0);
                                sendRequest("http://book.zongheng.com/chapter/1028707/61764524.html");
                                Toast.makeText(BookActivity.this,"第三章",Toast.LENGTH_SHORT).show();
                                break;
                        }
                        return true;
                    }
                });
            }
        });
    }


    private void sendRequest(String uurl) {
        OkHttpClient client=new OkHttpClient();
        final Request request=new Request.Builder()
                .url(uurl)
                .build();
        Call call=client.newCall(request);
        call.enqueue(new Callback() {
            @Override
            public void onFailure( Call call,  IOException e) {
                Log.w("fail","fail to ask");
            }

            @Override
            public void onResponse( Call call,  Response response) throws IOException {
                String str=response.body().string();

                Document document= Jsoup.parse(str);
                Element element=document.getElementsByClass("content").first();
                Elements element1 =element.getElementsByTag("p");
                String text="";
                for(int i=0;i<element1.size();i++){
                    text+=element1.get(i).text()+"\n";
                }
//                final String finalText = text;
//                MainActivity.this.runOnUiThread(new Runnable() {
//                    @Override
//                    public void run() {
//                        mainText.setText(finalText);
//                    }
//                });
                Message message =Message.obtain();
                message.what=1;
                message.obj=text;
                text="";
                handler.sendMessage(message);
            }
        });
    }
}

切换章节时需要使用smoothScrollto(0,0)来回到最初否则效果不佳。左上方在按钮上加了一个popupMenu实现一个选择章节的功能。上一章,下一章按钮也是同理。

在这里插入图片描述

电影列表部分

在主界面中还有另外一个电影按钮。

只运用了一个listview

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:fitsSystemWindows="true"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <ListView
        android:id="@+id/movie_list"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        />
    
</LinearLayout>

建立了一个本地服务器,我这里使用的是apache。(后面改成用了室友的服务器填了一些数据)
在htdocs目录下,创建json文件。存入一些内容。
比如

[{“name”:“Titanic”,“data”:“1997-12-19”,“director”:“James Cameron”},{“name”:“your name”,“data”:“2016-12-2”,“director”:“Makoto Shinkai”}]

然后在MovieActivity中解析这些数据并把这些数据放在相应的控件上。
电影相关的适配器和布局如下

public class MovieAdapter extends ArrayAdapter<Movie> {
    private int resourceId;

    public MovieAdapter(@NonNull Context context, int resource, @NonNull List<Movie> objects) {
        super(context, resource, objects);
        resourceId=resource;
    }

    @NonNull
    @Override
    public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
        Movie movie=getItem(position);
        View view= LayoutInflater.from(getContext()).inflate(resourceId,parent,false);
        ImageView img=view.findViewById(R.id.movie_image);
        TextView nameMovie=view.findViewById(R.id.movie_name);
        TextView dataMovie =view.findViewById(R.id.moive_data);
        TextView directorMovie =view.findViewById(R.id.movie_director);
        img.setImageResource(movie.img);
        nameMovie.setText(movie.getName());
        dataMovie.setText(movie.getData());
        directorMovie.setText(movie.getDirector());
        return view;
    }
}
public class Movie {
    public int img;
    String name;
    String data;
    String director;

    public Movie(int img,String name, String data, String director) {
        this.img =img;
        this.name = name;
        this.data = data;
        this.director = director;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getData() {
        return data;
    }

    public void setData(String data) {
        this.data = data;
    }

    public String getDirector() {
        return director;
    }

    public void setDirector(String director) {
        this.director = director;
    }
}

movie_item

<?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">
    <ImageView
        android:id="@+id/movie_image"
        android:layout_width="100dp"
        android:layout_height="100dp"/>
    <TextView
        android:layout_toRightOf="@+id/movie_image"
        android:id="@+id/movie_name"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:textSize="28sp"
        android:layout_marginLeft="10dp"
        />
    <TextView
        android:id="@+id/moive_data"
        android:layout_toRightOf="@+id/movie_image"
        android:layout_below="@+id/movie_name"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="上映时间:xxxx-xx-xx"
        android:gravity="center"
        android:textSize="20sp"/>
    <TextView
        android:id="@+id/movie_director"
        android:layout_toRightOf="@+id/movie_image"
        android:layout_below="@+id/moive_data"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="导演:xxx"
        android:gravity="center"
        android:textSize="20sp"/>

</RelativeLayout>
public class MovieActivity extends AppCompatActivity {
 private List<Movie> movieList=new ArrayList<>();
 ImageView imageView;
    MovieAdapter adapter;
 ListView listView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_movie);
        listView=findViewById(R.id.movie_list);
         adapter=new MovieAdapter(MovieActivity.this,R.layout.movie_item,movieList);
        listView.setAdapter(adapter);
        sendRequest();
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                Movie movie=movieList.get(position);
                Intent intent =new Intent(MovieActivity.this,MovieWebActivity.class);
                switch (movie.getName())
                {
                    case "Titanic":intent.putExtra("movie_url","https://baike.baidu.com/item/%E6%B3%B0%E5%9D%A6%E5%B0%BC%E5%85%8B%E5%8F%B7/6162581?fr=aladdin");
                        break;
                    case "your name":intent.putExtra("movie_url","https://baike.baidu.com/item/%E4%BD%A0%E7%9A%84%E5%90%8D%E5%AD%97%E3%80%82/19127928?fromtitle=%E4%BD%A0%E7%9A%84%E5%90%8D%E5%AD%97&fromid=19126915&fr=aladdin");
                        break;
                }
                startActivity(intent);
                /*Intent intent =new Intent(Intent.ACTION_VIEW);
                switch (movie.name)
                {
                    case "Titanic":intent.setData(Uri.parse("https://baike.baidu.com/item/%E6%B3%B0%E5%9D%A6%E5%B0%BC%E5%85%8B%E5%8F%B7/6162581?fr=aladdin"));
                    break;
                }
                 startActivity(intent);*/
            }
        });
    }
    private void sendRequest() {
        OkHttpClient client=new OkHttpClient();
        Request request =new Request.Builder()
                //.url("http://192.168.1.107/get_data.json")
                //这里输入你的ip
                .url("http://www.lazypet.top:3000/")
                .build();
        Call call=client.newCall(request);
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Log.w("result","fail to ask");
            }
            @Override
            public void onResponse(Call call, Response response) throws IOException {
                Gson gson =new Gson();
                String str=response.body().string();
                System.out.println(str);
                List<Movie> jsonsList=gson.fromJson(str,new TypeToken<List<Movie>>(){}.getType());
                for(int i=0;i<5;i++) {
                    Movie movie1 = new Movie(R.mipmap.titanic, jsonsList.get(0).getName(), jsonsList.get(0).getData(), jsonsList.get(0).getDirector());
                    Movie movie2 = new Movie(R.mipmap.yourname, jsonsList.get(1).getName(), jsonsList.get(1).getData(), jsonsList.get(1).getDirector());
                    movieList.add(movie1);
                    movieList.add(movie2);
                }
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        adapter.notifyDataSetChanged();
                    }
                });
            }
        });
    }

}

采用okhttp访问网络返回内容,采用GSON解析数据。
效果如图:
在这里插入图片描述
为了丰富一下效果又加了一个点击事件,可以根据列表中的名字跳转到对应的百度百科上面。运用的是webview。webview中需要用到的网址,是加在intent里传递过去的,又在webviewActivity中取出,然后加载,另外还有一种直接打开浏览器加载网址的方法都在上面的代码的注释中。


public class MovieWebActivity extends AppCompatActivity {
WebView webView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_movie_web);
        webView=findViewById(R.id.web_view);
        String data=getIntent().getStringExtra("movie_url");
        webView.getSettings().setJavaScriptEnabled(true);
        webView.loadUrl(data);
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode==KeyEvent.KEYCODE_BACK&webView.canGoBack()){
            webView.goBack();
            return true;
        }
        return super.onKeyDown(keyCode,event);
    }
}

重写了back键的用法,当能退出时一步一步的退。

至此第一个碎片界面也完成的差不多了。

标题栏半透明化

你可能会发现我在很多布局中都是用android:fitsSystemWindows="true"这句代码,这是为了让标题栏实现半透明效果并不会挡住我们界面内容所必须要加的一句代码。
那么怎么实现标题栏半透明效果呢?
我采用的方法是创建value-19文件添加styles.xml文件在其中加入如下代码

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <style name="AppTheme.Main" parent="AppTheme">
        <item name="android:windowTranslucentStatus">true</item>
    </style>

</resources>

而在原本的value的styles.xml中则加入了这段代码

    <style name="AppTheme.Main" parent="AppTheme">
        
    </style>

在配置文件将Theme改为AppTheme.Main,在此基础之上就可实现标题栏半透明。
说回android:fitsSystemWindows="true"这句代码,我查阅一些博客,大多数说是要将这段代码加在根布局中但是我试了一下,有些有用,但在一些复杂的布局中却没有用处甚至更改成了默认的灰色,而当我把这句代码加在设置颜色相关的控件中时,就能够成功显示。具体原因也还没有深入了解。

增加一些动画

最后为各个Activity之间的切换增加几个动画效果,显得更加丝滑一点。
同样在style中加入
<item name="android:windowAnimationStyle">@style/AnimationActivity</item>
然后继续完善在后面加入代码

    <style name="AnimationActivity" parent="@android:style/Animation.Activity">
        <!-- 打开Activity时,新进入的activity执行的动画-->
        <item name="android:activityOpenEnterAnimation">@anim/open_enter</item>
        <!-- 打开Activity时,原activity执行的动画-->
        <item name="android:activityOpenExitAnimation">@anim/open_exit</item>
        <!-- 打开Activity时,退出的activity执行的动画-->
        <item name="android:activityCloseExitAnimation">@anim/close_exit</item>
        <!-- 打开Activity时,重新显示activity执行的动画-->
        <item name="android:activityCloseEnterAnimation">@anim/close_enter</item>

    </style>

紧接着创建anim动画文件
完善这几个动画资源
open_enter

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
  <translate
      android:fromXDelta="100%"
      android:toXDelta="0%"
      android:duration="500"
      />
</set>

open_exit

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">

    <scale android:fromXScale="1.0"
        android:fromYScale="1.0"
        android:toXScale="0.8"
        android:toYScale="0.8"
        android:pivotX="50%"
        android:pivotY="50%"
        android:duration="500"
        />
</set>

close_enter

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">

    <scale android:fromXScale="0.8"
        android:fromYScale="0.8"
        android:toXScale="1.0"
        android:toYScale="1.0"
        android:pivotX="50%"
        android:pivotY="50%"
        android:duration="500"
        />
</set>

close_exit

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate
        android:fromXDelta="0%"
        android:toXDelta="100%"
        android:duration="500"
        />
</set>

第二个碎片

在第二个碎片中,我打算加一个音乐相关的页面。
在第三个碎片中,随便在加一些自己元素在里面就行了。
因为音乐界面运用到的依然是写界面+一些简单逻辑然后在运用一些播放音频的api就行了,自己写的过于简单,后面打算模仿写一个看起来高逼格的音乐app。所以就不在展示相关代码了。

第三个界面还没想好怎么写。

ok,这样简单的项目,轻松完成了。

  • 76
    点赞
  • 340
    收藏
    觉得还不错? 一键收藏
  • 24
    评论
初学者必看 1、LinearLayout Button、RadioGroup、 CheckBox 2、TableLayout 3、FrameLayout 霓虹灯效果 4、RelativeLayout 梅花效果 5、自定义view跟着触点走的小球 6、 ListView 列表视图 7、WebView web视图 8、ToggleButton 动态布局效果 9、AnalogClock 、 DigitalClock and Chronometer 时钟和数字日期 10、AutoCompleteTextView 根据输入自动补充可能的全部 11、Spinner View 选择框(弹出框形式选择) 12、DatePicker TimePicker View 日期时间选择器 13、ProgressBar View 普通进度条、显示在标题栏上的进度条 14、RatingBar View 评级 15、 SeekBar 拖动条,音量调节效果 16、ScrollView 、HorizontalScrollView 垂直和水平滚动条 17、ScrollView 、HorizontalScrollView 垂直和水平滚动条 18、ExpandableListView 分组可展开收缩的ListView 19、Notification 状态栏通知 20、GridView、ImageSwitcher 21、SmsManager 消息管理器,发短信(这里是模拟器只能给其它模拟器发短信) 22、Intent Action、Category属性 测试 23、系统 Action、Category属性 24、ClipDrawable 徐徐展开的风景 25、AnimationDrawable 会动的图片 26、Menu、SubMenu、ContextMenu xml配置menu 27、Attribute 自定义view的duration属性 控制图片的透明度 28、Bitmap、BitmapFactory 图形与图像处理 29、Canvas 绘制自定义图形 30、Canvas 采用双缓存实现画图板 31、SharedPreference 简单的key-value数据存取 32、SQLiteDatabase 安卓客户端的嵌入式数据库 33、GestureDetector + ViewFlipper实现翻页效果 34、GestureLiberay 自定义手势 35、GestureLiberay 通过自定义的手势实现用户操作 36、TextToSpeech 语音朗读 37、ContentProvider、ContentResolver 应用之间共享数据 38、 Service 相当于没有界面的activity 39、Activity与Service运行中通信 40、Service 相当于没有界面的activity 41、AIDL Service android中的跨进程调用 客户端,服务端见AidlService 42、BroadcastReceiver 接收广播消息 43、非UI线程中不能操作UI线程中的View测试 44、ImageSwitcher animation gesture实现可以滑动的跑马灯 45、下载状态栏显示下载进度 46、Gallery3d效果 47、ListView 上拉加载更多效果 48、异步加载图片的二级缓存技术 49、QQ的好友列表展示效果 50、Fragment + ViewPager实现tab滑动切换 51、能够显示在桌面前面的的歌词效果 52、activity切换特效
一个简单的 Android GPS 项目实例可以包括以下步骤: 1. 在 AndroidManifest.xml 文件中添加 ACCESS_FINE_LOCATION 权限。 2. 在布局文件中添加一个 TextView 用于显示 GPS 信息。 3. 在 Activity 中获取 LocationManager 实例,并注册 LocationListener。 4. 在 LocationListener 中实现 onLocationChanged 方法,获取 GPS 信息并更新 TextView 显示。 5. 在 Activity 的 onResume 方法中请求 GPS 更新。 6. 在 Activity 的 onPause 方法中停止 GPS 更新。 以下是一个简单的 Android GPS 项目实例代码: AndroidManifest.xml 文件: ```xml <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> ``` activity_main.xml 布局文件: ```xml <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <TextView android:id="@+id/gps_info" android:layout_width="match_parent" android:layout_height="wrap_content" android:textSize="20sp" /> </LinearLayout> ``` MainActivity.java 文件: ```java import android.Manifest; import android.content.pm.PackageManager; import android.location.Location; import android.location.LocationListener; import android.location.LocationManager; import android.os.Bundle; import android.widget.TextView; import androidx.appcompat.app.AppCompatActivity; import androidx.core.app.ActivityCompat; public class MainActivity extends AppCompatActivity implements LocationListener { private TextView gpsInfoTextView; private LocationManager locationManager; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); gpsInfoTextView = findViewById(R.id.gps_info); locationManager = (LocationManager) getSystemService(LOCATION_SERVICE); // 检查是否有 ACCESS_FINE_LOCATION 权限 if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { // 如果没有权限,则请求权限 ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 1); } else { // 如果已经有权限,则注册 LocationListener 并请求 GPS 更新 locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this); } } @Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == 1) { if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { // 如果用户授予了权限,则注册 LocationListener 并请求 GPS 更新 locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this); } } } @Override public void onLocationChanged(Location location) { // 获取 GPS 信息并更新 TextView 显示 double latitude = location.getLatitude(); double longitude = location.getLongitude(); gpsInfoTextView.setText("Latitude: " + latitude + "\nLongitude: " + longitude); } @Override public void onStatusChanged(String provider, int status, Bundle extras) {} @Override public void onProviderEnabled(String provider) {} @Override public void onProviderDisabled(String provider) {} @Override protected void onPause() { super.onPause(); // 停止 GPS 更新 locationManager.removeUpdates(this); } } ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值