水平有限,本文相當基礎!!
自己從六月份斷斷續續的學習了一些android入門的知識,
至于為什么要學android,其實還是為了學習Java,對Java的不熟悉,使得學習了一些java知識之后不知道如何運用,所以選擇了android來做一些可以看出效果的一些應用,
寫這篇博客的目的,是為了對android知識的進行總結和鞏固,一邊寫一邊對原來代碼進行優化,
之后會把重心繼續放在java上,
這個app界面是本著模仿學校里一個常用軟體來做的,因為能力不足,功能有很大不同,
這個app也是從我學android就開始做的,然后在一點點加新學的東西進去,所以有些地方不規范也是這個原因,可以看出很多新手菜鳥的影子,
粗略把結構分成了這樣

首先自定義一個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,
先實作注冊頁面

方法大同小異,不在重復,
接下來就是實作注冊功能,
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就需要單獨來寫一個配接器了,
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;
ListView listView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_movie);
listView=findViewById(R.id.movie_list);
MovieAdapter adapter=new MovieAdapter(MovieActivity.this,R.layout.movie_item,movieList);
sendRequest();
listView.setAdapter(adapter);
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輸入你自己當前的ip
.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();
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);
}
}
});
}
}
采用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,這樣簡單的專案,輕松完成了,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/218838.html
標籤:AI
