这是指尖菜谱App正式进入开发阶段,androidstudio新建一个项目,这里我包名起名为com.hgs.zjcp,建立好项目后我们将要导入上一篇所讲的一些类库。
接下的具体如何导入我就不多说了,请参照我给出的链接,上面有详细的导入方法,以及内容介绍。
1、okhttputils的导入:https://github.com/hongyangAndroid/okhttputils
2、butterknife的导入:https://github.com/JakeWharton/butterknife
(熟悉此框架的用法请详情http://jakewharton.github.io/butterknife/)
3、cardview、recycleview与Gson的导入:File->Project Structure->app->Dependencies-> + ->Library Dependency 找到需要的包点击Ok继续ok,这时androidstudio就知道帮你依赖相应的类库了。
最终的libs目录结构:
以及依赖的类库:
为了方便操作作者写了一个对okhttputils的再度封装类,使得更加简单实用NetUtils:
public class NetUtils { private static String TAG = "OKHTTP_NETUTILS"; /** * @param url * @param params * @param stringCallback * @return */ public static void get(String url, Mapparams, StringCallback stringCallback) { GetBuilder okHttpUtils = OkHttpUtils.get().url(url); if (params != null) { params.keySet(); //添加参数 for (String k : params.keySet()) { okHttpUtils.addParams(k, params.get(k)); } } okHttpUtils .build() .execute(stringCallback); } /** * @param url * @param params post的参数 * @param callBack * @return */ public static void post(String url, Map params, Callback callBack) { PostFormBuilder okHttpUtils = OkHttpUtils.post().url(url); if (params != null) { params.keySet(); //添加参数 for (String k : params.keySet()) { okHttpUtils.addParams(k, params.get(k)); } } okHttpUtils .build() .execute(callBack); } /** * 提交json内容 * * @param url * @param JSONContent 要提交的JSON内容 * @param stringCallback */ public static void postJson(String url, String JSONContent, StringCallback stringCallback) { OkHttpUtils .postString() .url(url) .content(JSONContent) .mediaType(MediaType.parse("application/json; charset=utf-8")) .build() .execute(stringCallback); } /** * post提交文件 * * @param url * @param file * @param stringCallback */ public static void postFile(String url, File file, StringCallback stringCallback) { OkHttpUtils .postFile() .url(url) .file(file) .build() .execute(stringCallback); } /** * 形如表单 * 表单的形式提交文件,可多个文件一起提交 * * @param url * @param formFiles 提交的文件 * @param params * @param headers * @param stringCallback */ public static void postFile(String url, List formFiles, Map params, Map headers, StringCallback stringCallback) { PostFormBuilder okHttpUtils = OkHttpUtils.post(); for (PostFormFile formFile : formFiles) { okHttpUtils.addFile(formFile.getName(), formFile.getFileName(), formFile.getFile()); } okHttpUtils .url(url) .params(params)// .headers(headers)// .build()// .execute(stringCallback); } /** * Bitmap的下载获取 * * @param url * @param bitmapCallback */ public static void getBitmap(String url, BitmapCallback bitmapCallback) { OkHttpUtils .get()// .url(url)// .build()// .execute(bitmapCallback); } /** * 文件 * * @param url * @param fileCallBack 文件的回调 */ public static void downLoadFile(String url, FileCallBack fileCallBack) { OkHttpUtils// .get()// .url(url)// .build()// .execute(fileCallBack); } }
PostFromFile类:
public class PostFormFile {
private String name;
private String fileName;
private File file;
public PostFormFile() {
}
public PostFormFile(String name, String fileName, File file) {
this.name = name;
this.fileName = fileName;
this.file = file;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getFileName() {
return fileName;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
public File getFile() {
return file;
}
public void setFile(File file) {
this.file = file;
}
}
以上代码可以直接拷贝到您的项目中,直接调用就行。基本的使用方法这里我以get为例
public void getMenuList(String cid, int page) {
//get使得参数,NetUtils中要传参数,都是以Map的形式闯入,如果没有参数直接传入null即可。不过postFile例外,不能为空,得传入一个实例
Map param = new HashMap<>();
param.put("key", MyApplication.MOBKEY);
param.put("cid", cid);
//String uri ,Map param ,new StringCallback()
NetUtils.get(NetUri.MOBCook.COOK_CID_SEARCH, param, new StringCallback() {
@Override
public void onError(Call call, Exception e, int i) {//一些错误回到都在这,如网络不可用等等
}
@Override
public void onResponse(String s, int i) {
System.out.println(s);//get得到的数据都在这
}
});
}
是不是感觉又简单了好多,您再也不用去写那一大堆自己封装的网络相关代码了。,还有一些操作我就不写了,自己看我上面给出的地址,一定要按照那些流程操作,不然无法使用okhttp
对于butterknife也一样,一定仔细更加github上的流程操作。
最终项目的build.Gradle(Module:app)代码:
apply plugin: 'com.android.application'
apply plugin: 'android-apt'
android {
compileSdkVersion 23
buildToolsVersion "24.0.2"
defaultConfig {
applicationId "com.hgs.zjcp"
minSdkVersion 16
targetSdkVersion 23
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.4.0'
compile files('libs/okhttp-3.4.1.jar')
compile files('libs/okhttputils-2.6.2.jar')
compile files('libs/okio-1.9.0.jar')
compile 'com.jakewharton:butterknife:8.4.0'
apt 'com.jakewharton:butterknife-compiler:8.4.0'
compile 'com.android.support:cardview-v7:23.2.0'
compile 'com.google.code.gson:gson:2.7'
compile 'com.android.support:recyclerview-v7:23.4.0'
}
build.Gradle(Project:ZJCP)代码:
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.1.0'
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
}
}
allprojects {
repositories {
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
好了项目的基本准备工作就做完了。如果您尝试着模仿如有不同,或者报错,请注意检查什么地方是否有漏。
正式的代码部分
首先我们要做这样一个效果如图
我们
当点击主页时显示0,点击菜谱显示1,以此类推,主页图中你有没发现2数字在状态栏上,也就是说,我们需要去掉状态栏,先不急。
接下来将实现一个bottom导航条。
经过思考后决定采用RadioButton+RadioGroup实现导航条,界面代码如下:
用到的style:
@null
center
0.5
通过include将bottom加入到主界面中
效果图如下
底部导航条做好了,那么接下来将要是每个导航条点击有不同界面处理的效果吧,于是作者采用四个fragment+ViewPager的方式做整体的框架。
目录结构:
具体代码:
public class MainActivity extends AppCompatActivity {
// RadioButton rbMain,rbMenu,rbChoice,rbMine;
Fragment[] fragments = {MainFragment.newInstance(), MenuFragment.newInstance(),
ChoiceFragment.newInstance(), MineFragment.newInstance()};
private FragmentManager fm;
@BindView(R.id.main_viewpager)
ViewPager mViewPager;
private MyPagerAdapter mPagerAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//去掉标题栏,使内容,充满标题栏
getWindow().requestFeature(Window.FEATURE_NO_TITLE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
Window window = getWindow();
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS
| WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
window.setStatusBarColor(Color.TRANSPARENT);
window.setNavigationBarColor(Color.TRANSPARENT);
}
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
fm = getSupportFragmentManager();
mPagerAdapter = new MyPagerAdapter(fm);
mViewPager.setAdapter(mPagerAdapter);
mViewPager.setOffscreenPageLimit(4);//增加缓存pager,以免被销毁
}
private void initFragment() {
}
@OnClick(R.id.bottom_rb_main)
public void rbMainClick() {
mViewPager.setCurrentItem(0);
}
@OnClick(R.id.bottom_rb_menu)
public void rbMenuClick() {
mViewPager.setCurrentItem(1);
}
@OnClick(R.id.bottom_rb_choice)
public void rbChoiceClick() {
mViewPager.setCurrentItem(2);
}
@OnClick(R.id.bottom_rb_mine)
public void rbMineClick() {
mViewPager.setCurrentItem(3);
}
/**
* FragmentPagerAdapter与FragmentStatePagerAdapter不同之处在于前者会remove不需要的fragment,后者只是销毁的view,但对象依然还在
*/
class MyPagerAdapter extends FragmentPagerAdapter {
public MyPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
return fragments[position];
}
@Override
public int getCount() {
return fragments.length;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
}
}
}
fragment的代码,这里只给出一个实例
public class MenuFragment extends BaseFragment {
private static MenuFragment menuFragment;
public static MenuFragment newInstance() {
if (menuFragment == null) {
menuFragment = new MenuFragment();
}
return menuFragment;
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_menu, container, false);
return view;
}
}
fragment的布局任意你可以随便标识下如0,1,2,3
这样以便区分不同的fragment
好了,运行下试一试看看效果
是不是和效果和我上面给出的一样;
注意
getWindow().requestFeature(Window.FEATURE_NO_TITLE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
Window window = getWindow();
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS
| WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
window.setStatusBarColor(Color.TRANSPARENT);
window.setNavigationBarColor(Color.TRANSPARENT);
块代码上后,即可实现,内容显示在状态条上。
动手试试吧。