之前写过一个项目,想把自己写的里面的一些技术点记录下来,也相当于给自己做笔记。同时也跟大家一起分享一下,若碰到同样的问题的朋友,也可以相互交流一下,新手上路,请多多指教。在那期间呢,碰到以及出现过许多的错误,这里就在这记录一下。
1、关于找错:这仅对于新手来说:1、当你思路不清楚时,或你为什么达不到你要的效果时,你要学会从头理,理清顺序,看自己是在哪个环节哪个步骤写错了,比如可能你的方法没写全之类的小问题,这要耐心,毕竟心急吃不了热豆腐。
2、高级控件自动补全 《Autocompl》 同一个适配器(adapter)可以作用于多个数据 需要通过适配器拿到数据 一般默认两个(也就是要写两个字符串才提示) 如需默认一个需加属性complettionThreshold=”1” (2,)多个自动补全框《multiautocopleteTextview》 分割符: 默认逗号 new multAutocompl 下拉列表 《spinner》 listview 集合
3、如果一个项目区间引用第三方控件 如果要删除第三方控件的话 其另一个引用他的控件也要删除其引用的那行代码
4、解析viewpager+xml 只需解析布局 主要代码如下:
View chanese= LayoutInflater.from(MainActivity.this).inflate(R.layout.activity_chinese,null);
但解析viewpager+activity需要得到布局 也需要其activity (包含java代码)主要代码如下:
LocalActivityManager manager=new LocalActivityManager(this,true);
manager.dispatchCreate(savedInstanceState);
Intent intent=new Intent(MainActivity.this,ChineseActivity.class);
View chinese= manager.startActivity("viewID",intent).getDecorView();//转成view
5、数据库版本问题 不能一个大 一个小 只能一起升级 这样就不会报版本号的错误
接下来就讲讲我项目中用到的一些技术点吧,由于一些问题我就不截图了:
首先当app首次安装必定有个导航页;
其用到的是 sharedprefence+viewpager+handler
刚开始进是有个欢迎界面,在欢迎界面里面判断你是否是第一次进入;其代码如下:
activity:
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Toast;
public class WelcomeActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_welcome);
shipToNavigationOrFrame();
}
//判断且实现应跳转导航动画还是主界面
private void shipToNavigationOrFrame() {
// Toast.makeText(WelcomeActivity.this, "3333", Toast.LENGTH_SHORT).show();
boolean firstFlag; //是否首次安装
SharedPreferences sharedPreferences = getSharedPreferences("flag", MODE_PRIVATE);
firstFlag = sharedPreferences.getBoolean("first", true);
final Intent intent = new Intent();
if (firstFlag) {
// Toast.makeText(WelcomeActivity.this, "4444", Toast.LENGTH_SHORT).show();
intent.setClass(this, NavigationActivity.class);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putBoolean("first", false);
editor.apply(); //apply与commit作用相同,虽没返回值,但效率更高
} else {
intent.setClass(this, SplashhActivity.class);
}
new Handler().postDelayed(new Runnable() { //延时1.5秒
@Override
public void run() {
startActivity(intent);
WelcomeActivity.this.finish();
finish();
}
},1500);
}}
其对应的xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_welcome"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
tools:context="com.example.activity_appui.WelcomeActivity"
android:background="@drawable/welcome"
>
</LinearLayout>
接下来就是导航页了,其代码如下:
activity:
import android.content.Intent;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.List;
public class NavigationActivity extends AppCompatActivity {
private ViewPager vPager;
private ViewGroup pointGroup;
private List vList;
private ImageView[] pointImgViews; //装载导航小圆点
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_navigation);
/// Toast.makeText(NavigationActivity.this, "555", Toast.LENGTH_SHORT).show();
initView();
setvPager();
addPoints();
setAdapterForViewPager();
}
//加载主页面控件
private void initView(){
// Toast.makeText(NavigationActivity.this, "555", Toast.LENGTH_SHORT).show();
vPager = (ViewPager)findViewById(R.id.navigation_vp);
pointGroup = (ViewGroup)findViewById(R.id.viewPoints);
// getSupportActionBar().hide();
}
private void setvPager(){
LayoutInflater inflater = getLayoutInflater();
vList = new ArrayList<View>();
vList.add(inflater.inflate(R.layout.navigation_page,null));
vList.add(inflater.inflate(R.layout.navigation_page2,null));
vList.add(inflater.inflate(R.layout.navigation_page3,null));
PagerAdapter myAdapter = new PagerAdapter(){
@Override
public int getCount() {
return vList.size();
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
// super.destroyItem(container, position, object);
container.removeView((View) vList.get(position));
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
container.addView((View) vList.get(position));
return vList.get(position);
}
@Override
public boolean isViewFromObject(View view, Object object) {
return view==object;
}
};
vPager.setAdapter(myAdapter);
}
private void addPoints(){
ImageView pointImgView;
pointImgViews = new ImageView[vList.size()]; //确定小圆点的个数
//动态添加小圆点
for(int i=0; i<vList.size(); i++) {
pointImgView = new ImageView(NavigationActivity.this);
pointImgView.setLayoutParams(new ViewGroup.LayoutParams(25, 25)); //设置圆点大小
pointImgView.setPadding(5, 0, 5, 0);
pointImgViews[i] = pointImgView;
// 默认选中的是第一张图片,此时第一个小圆点是选中状态,其他不是
if (i == 0)
pointImgViews[i].setImageDrawable(getResources().getDrawable(
R.drawable.i1));
else
pointImgViews[i].setImageDrawable(getResources().getDrawable(
R.drawable.i3));
// 将imageviews添加到小圆点视图组
pointGroup.addView(pointImgViews[i]);
}
}
//添加监听器,将相应页面的小圆点设置为选中状态
private void setAdapterForViewPager(){
vPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener()
{
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
for (int i = 0; i < pointImgViews.length; i++) {
// 当前view下设置小圆点为未选中状态
pointImgViews[i].setImageDrawable(getResources().getDrawable(
R.drawable.i1));
//设置小圆点为选中状态
if(position == i)
pointImgViews[i].setImageDrawable(getResources().getDrawable(
R.drawable.i3));
}
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
}
//点击button后调用,跳转到主界面,勿忘设置参数
public void shipToFrame(View v){
Intent intent = new Intent(this, DownActivity.class);
startActivity(intent);
this.finish();
}
}
xml:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
tools:context="com.example.activity_appui.NavigationActivity">
<android.support.v4.view.ViewPager
android:id="@+id/navigation_vp"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
<LinearLayout
android:id="@+id/viewPoints"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:layout_marginBottom="15dp"
android:gravity="center_horizontal"
android:orientation="horizontal"
android:paddingBottom="150dp">
</LinearLayout>
</FrameLayout>
因为导航页就是一张张滑动的,就用viewpager+activity,activity里面就放张图片,这里就贴一个activity出来,其余都是一样的。
xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:background="@drawable/navigation_image">
</RelativeLayout>
这样就能实现导航页了。当你第二次登录时,你便进入引导页,像qq那样每次进去便出现那个熟悉的小企鹅。可以用countdonwntime,线程也可以实现这个效果。本人就是用线程实现的。代码如下:
activity:
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class SplashhActivity extends AppCompatActivity {
private ImageView splash_img;
private TextView tv_control;
private TextView tv_control2;
private Intent intent;
private Thread thread;
private boolean bool;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splashh);
splash_img = (ImageView) findViewById(R.id.splash_img);
tv_control = (TextView) findViewById(R.id.tv_control);
tv_control2 = (TextView) findViewById(R.id.tv_control2);
// 跳转页面
intent = new Intent(SplashhActivity.this, DownActivity.class);
bool = true;
thread = new Mythread();
thread.start();
}
//处理
Handler handler = new Handler() {
public void handleMessage(Message msg) {
super.handleMessage(msg);
int i = msg.what;
tv_control.setText(i + "秒");
}
};
public void jump(View view) {
bool = false;
//开始跳
startActivity(intent);
finish();
}
//子线程
class Mythread extends Thread {
@Override
public void run() {
super.run();
for (int i = 5; i >= 0; i--) {
handler.sendEmptyMessage(i);
SystemClock.sleep(1000);
}
//当他等于true的时候跳
while (bool) {
//跳转 Intent 意图
Intent intent = new Intent(SplashhActivity.this, DownActivity.class);
//开始跳
startActivity(intent);
break;
}
//直接返回主页面
finish();
}
}
}
xml:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_splashh"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.activity_appui.SplashhActivity">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/g_1"
android:id="@+id/splash_img"
android:scaleType="fitXY"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/tv_control"
android:background="#3f5348"
android:textSize="30sp"
android:layout_gravity="right"
android:text="倒计时"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/tv_control2"
android:background="#3f5348"
android:textSize="30sp"
android:layout_gravity="bottom|right"
android:onClick="jump"
/>
</FrameLayout>
进了引导页之后自然便进入主界面,主界面排版:textview,ViewPager,ViewPager+fragment…….
其中用ViewPager实现图片自动播放加点击事件,一般像一个学习app这样的功能就是点击任意一张图片你便能进入其自己app公众号或是其自己的网站还有的就是广告。
其代码如下:
activity:
private ImageView topmain_imags;
//得到图片集合
int images[] = {R.drawable.guid1, R.drawable.guid2, R.drawable.guid3, R.drawable.guid4};
//定义一个全局变量 当前的变量为0
int currentIndex = 0;
private Thread thread;
private Spinner main_spinner;
private TextView tv_class;
private TextView tv_c1;
private ListView lv_main;
private ViewPager vp_viewpage_activity;
private List<View> list;//表示装载滑动的布局
private RadioGroup rp_grooup_clazz;
private RadioGroup rg_main;
List<Fragment> view = new ArrayList<>();
private RadioGroup rg_down;
private Button rb_study;
private Button rb_find;
private Button rb_my;
private ViewPager vp;
private List<View> views = new ArrayList<View>();
private ImageView iv, iv2;//iv代表小圆点,iv2代表viewPager的图片
private int images2[] = {R.drawable.guid1, R.drawable.guid2, R.drawable.guid3, R.drawable.guid4};
private Myadapter mAdapter;
private final int AUTO_MSG = 1;
private static final int PHOTO_CHANGE_TIME = 2000;
private int index = 0;
private long exitTime = 0;
//Handler导包为android.os.Handler
private Handler myhandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case AUTO_MSG:
if (index == images.length) {
index = 0;
}
vp.setCurrentItem(index++);//收到消息后设置当前要显示的图片
myhandler.sendEmptyMessageDelayed(AUTO_MSG, 2000);
break;
default:
break;
}
// super.handleMessage(msg);
}
};
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Toast.makeText(MainActivity.this, "1111", Toast.LENGTH_SHORT).show();
//图片id
//topmain_imags = (ImageView) findViewById(R.id.topmain_imags);
vp = (ViewPager) findViewById(R.id.vp);
for (int i = 0; i < images.length; i++) {
iv2 = new ImageView(this);
iv2.setImageResource(images[i]);
views.add(iv2);
}
vp.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
iv = (ImageView) MainActivity.this.findViewById(images2[position]);
//iv.setImageResource(R.drawable.go_next);
for (int i = 0; i < images2.length; i++) {
if (i != position) {
iv = (ImageView) MainActivity.this.findViewById(images2[i]);
//iv.setImageResource(R.drawable.next_null);
}
}
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
myhandler.sendEmptyMessageDelayed(AUTO_MSG, 2000);
//轮播图片的适配器
vp.setAdapter(new MyImageAdapter());
//图片的适配器
class MyImageAdapter extends PagerAdapter {
@Override
public int getCount() {
return views.size();
}
@Override
public Object instantiateItem(ViewGroup container, final int position) {
View v = views.get(position);
v.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int i = position + 1;
if (i == 1) {
Intent intent = new Intent();
//给intent设置action
intent.setAction(Intent.ACTION_VIEW);
//设置数据
intent.setData(Uri.parse("http://www.xuexifangfa.com/xuexifangfa/135.html"));
startActivity(intent);
}
if (i ==2) {
Intent intent = new Intent();
//给intent设置action
intent.setAction(Intent.ACTION_VIEW);
//设置数据
intent.setData(Uri.parse("http://www.xuexifangfa.com/xuexifangfa/135.html"));
startActivity(intent);
}
if (i ==3) {
Intent intent = new Intent();
//给intent设置action
intent.setAction(Intent.ACTION_VIEW);
//设置数据
intent.setData(Uri.parse("http://www.xuexila.com/time/497904.html"));
startActivity(intent);
}
if (i==4) {
Intent intent = new Intent();
//给intent设置action
intent.setAction(Intent.ACTION_VIEW);
//设置数据
intent.setData(Uri.parse("http://www.xiaogushi.com/Article/chali/"));
startActivity(intent);
}
// Toast.makeText(MainActivity.this, "这是第" + i + "张图片", Toast.LENGTH_SHORT).show();
}
});
container.addView(v);
return v;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
View v = views.get(position);
container.removeView(v);
}
@Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
}
xml:
<android.support.v4.view.ViewPager
android:id="@+id/vp"
android:layout_width="match_parent"
android:layout_height="80dp"
/>
主页面需显示各个科目,考虑到需装许多数据,便采用了ViewPager+Fragment 由于Fragment都是一样的 这里我就只贴一个了,
先贴的是activity:
xml:
<android.support.v4.view.ViewPager
android:layout_width="wrap_content"
android:layout_height="0dp"
android:id="@+id/vp_viewpage_activity"
android:layout_weight="1"
>
</android.support.v4.view.ViewPager>
其对应的activity:
List<Fragment> view = new ArrayList<>();
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//得到viewpager 课程的viewpager
vp_viewpage_activity = (ViewPager) findViewById(R.id.vp_viewpage_activity);
// 获得对象集合
view.add(new ChineseFragment());
view.add(new MathFragment());
view.add(new EnglishFragment());
view.add(new HistoryFragment());
view.add(new GeographyFragment());
view.add(new LifeFragment());
view.add(new ChemistryFragment());
view.add(new GovermentFragment());
view.add(new PhysicsFragment());
//调用适配器
vp_viewpage_activity.setAdapter(new Myadapter(getSupportFragmentManager()));
//碎片的适配器
class Myadapter extends FragmentPagerAdapter {
public Myadapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
return view.get(position);
}
@Override
public int getCount() {
return view.size();
}
}
碎片activity:
import android.content.Intent;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.example.activity_appui.R;
import com.example.activity_appui.com.example.Chinese_famous_write;
import com.example.activity_appui.com.example.Chinese_pager_up;
import com.example.activity_appui.com.example.Chinese_reader;
import com.example.activity_appui.com.example.Chinese_base;
public class ChineseFragment extends Fragment {
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.activity_chinese, null);
view.findViewById(R.id.tv_chinese).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// Toast.makeText(getContext(), "asdasd", Toast.LENGTH_SHORT).show();
Intent intent=new Intent(getActivity(), Chinese_base.class);
startActivity(intent);
}
});
view.findViewById(R.id.tv_chinese2).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent=new Intent(getActivity(), Chinese_famous_write.class);
startActivity(intent);
}
});
view.findViewById(R.id.tv_chinese3).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent=new Intent(getActivity(), Chinese_pager_up.class);
startActivity(intent);
}
});
view.findViewById(R.id.tv_chinese4).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent=new Intent(getActivity(), Chinese_reader.class);
startActivity(intent);
}
});
return view;
}
}
xml就不贴了。
这里关于选中变颜色的问题:你只需在values下面的colors.xml里面设置就行了。
然后你开始点单元做题,比如你点击语文做阅读理解题,数据库已经建好了关于语文分类表,你只需要给它设置一个监听事件,然后写个根据类别查询的sql语句就行了。
之后就出现了相应的题目,对于做题,先是需要你选的答案需要与数据库的答案相匹配。如果你的答案正确了便怎样,错了便怎样。像我就是如果选择正确了,便为绿色,错了便为红色。这个的话自己可以写个选择器引用就行了。
这样便能实现一个答题的效果,同时还有一些其他的功能,像一般这样的app都会有各种答题方式,如顺序练习,章节练习,随机练习等等……这些就不一一说了,这个只需修改sql语句,其实现的原理都是一样的。最后想说的是要多勇敢的尝试,不管难不难,都要去尝试,只有尝试了才有资格说难不难,要多给自己机会。还有就是需要思路清晰,把思路清晰了之后再下手,这样效率更高。先写到这,以后有机会再写。