Android项目—帖话APP

项目介绍

  • 贴话APP实现的功能类似于百度贴吧,实现发帖,读帖,修改帖,删帖功能,
  • 项目特色在于借助个人服务器的数据库实现网络服务,利用本地LitaPal实现用户数据缓存。
  • 没有唯一用户的说法,使用人可以以任何用户名发帖,他人发帖可以看到。
  • 实现了NavigationView侧边栏功能和WebView个人博客,上传图片的功能,支持用户登录,头像上传和帖子图片上传。
  • 设计使用高德地图开发包实现地图功能。
  • 使用CardView美化RecylerView,支持ToolBarScrolling美化页面动画。

关注博客

GaoMing’s Web

项目搭建

首页

  • 首页采用Android Stdio模板(自带侧边栏),首页采用碎片,用RecylerViewCardView搭建,侧边栏采用NavigationView搭建。

    public class MainActivity extends AppCompatActivity  
            implements NavigationView.OnNavigationItemSelectedListener {  
        private static Connection conn = null;  
        private static PreparedStatement stmt = null;  
        private SwipeRefreshLayout swipeRefreshLayout;  
        private List<News> sNewsList = new ArrayList<News>();  
        @Override  
        protected void onCreate(Bundle savedInstanceState) {  
            super.onCreate(savedInstanceState);  
            setContentView(R.layout.activity_main);  
            Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);  
            toolbar.setTitle("主页");  
             setSupportActionBar(toolbar);  
            DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);  
            ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(  
                    this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);  
            drawer.setDrawerListener(toggle);  
            toggle.syncState();  
            NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);  
            navigationView.setNavigationItemSelectedListener(this);  
        }  
        @Override  
        public void onBackPressed() {  
            DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);  
            if (drawer.isDrawerOpen(GravityCompat.START)) {  
                drawer.closeDrawer(GravityCompat.START);  
            } else {  
                super.onBackPressed();  
            }  
        }  
        @Override  
        public boolean onCreateOptionsMenu(Menu menu) {  
            // Inflate the menu; this adds items to the action bar if it is present.  
            getMenuInflater().inflate(R.menu.main, menu);  
            return true;  
        }  
        @Override  
        public boolean onOptionsItemSelected(MenuItem item) {  
            int id = item.getItemId();  
            if (id == R.id.action_settings) {  
                Intent intent = new Intent(MainActivity.this, PublishPost.class);  
                startActivity(intent);  
                item.setIntent(intent);  
            }  
            return super.onOptionsItemSelected(item);  
        }  
        @SuppressWarnings("StatementWithEmptyBody")  
        @Override  
        public boolean onNavigationItemSelected(MenuItem item) {  
            // Handle navigation view item clicks here.  
            int id = item.getItemId();  
            if (id == R.id.nav_camera) {  
                Intent intent = new Intent();  
                intent.setClass(MainActivity.this, PublishPost.class);  
                startActivityForResult(intent, 1);  
            } else if (id == R.id.nav_gallery) {  
                Intent intent = new Intent();  
                intent.setClass(MainActivity.this, WebBlog.class);  
                startActivity(intent);  
            } else if (id == R.id.nav_slideshow) {  
      
            } else if (id == R.id.nav_manage) {  
      
            } else if (id == R.id.nav_share) {  
      
            } else if (id == R.id.nav_send) {  
      
            }  
            return true;  
        }  
        @Override  
        protected void onActivityResult(int requestCode, int resultCode, Intent data) {  
            switch (requestCode) {  
                case 1:  
                    if (requestCode == RESULT_OK) {  
                        String result = data.getStringExtra("message");  
                        finish();  
                        Intent intent = new Intent(this, MainActivity.class);  
                        startActivity(intent);  
                        Toast.makeText(MainActivity.this, result, Toast.LENGTH_SHORT).show();  
                    }  
            }  
        }  
    }  
    
    
  • 其中,onCreate函数初始化界面,引入ToolBar和NavigationView,onNavigationItemSelected函数设置侧边栏的点击事件的响应,onOptionsItemSelected函数设置ToolBar右边下拉框点击事件的响应。

  • 布局

    <?xml version="1.0" encoding="utf-8"?>  
    <android.support.v4.widget.DrawerLayout 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:id="@+id/drawer_layout"  
        android:layout_width="match_parent"  
        android:layout_height="match_parent"  
        android:fitsSystemWindows="true"  
        tools:openDrawer="start">  
        <include  
            layout="@layout/app_bar_main"  
            android:layout_width="match_parent"  
            android:layout_height="match_parent" />  
        <android.support.design.widget.NavigationView  
            android:id="@+id/nav_view"  
            android:layout_width="wrap_content"  
            android:layout_height="match_parent"  
            android:layout_gravity="start"  
            android:fitsSystemWindows="true"  
            app:headerLayout="@layout/nav_header_main"  
            app:menu="@menu/activity_main_drawer">  
        </android.support.design.widget.NavigationView>  
    </android.support.v4.widget.DrawerLayout>  
    
    
  • 其中<include>导入主页面,<android.support.design.widget.NavigationView>标签设置侧边栏,app:headerLayoutapp:menu设置侧边栏的头部和身体。

首页碎片显示

  1. 首页内容显示采用碎片+RecylerView+CardView,核心代码如下

    public class NewsTitleFragment extends Fragment {  
        private boolean isTwoPane;  
        private static Connection conn = null;  
        private static PreparedStatement stmt = null;  
        private List<News> sNewsList = new ArrayList<News>();  
        private static final CountDownLatch ctl = new CountDownLatch(1);  
        private SwipeRefreshLayout swipeRefreshLayout;  
        private NewsAdapter newsAdapter = new NewsAdapter();  
        @Nullable  
        @Override  
        public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {  
            View view = inflater.inflate(R.layout.news_title_frag, container, false);  
            RecyclerView newsTitleRecyclerView = (RecyclerView) view.findViewById(R.id.news_title_recycle_view);  
            LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity()) {  
                @Override  
                protected int getExtraLayoutSpace(RecyclerView.State state) {  
                    return 300;  
                }  
            };  
            newsTitleRecyclerView.setLayoutManager(layoutManager);  
            @SuppressLint("HandlerLeak") final  
            Handler handler = new Handler() {  
                @Override  
                public void handleMessage(Message msg) {  
                    sNewsList = (List<News>) msg.obj;  
                    Log.d("sNewList.length : ", String.valueOf(sNewsList.size())); 
                }  
            };  
            Thread thread = null;  
            thread = new Thread(new Runnable() {  
                @Override  
                public void run() {  
                    Log.d(TAG, "ppppp: ???");  
                    try {  
                        conn = MySQLConnections.getConnection("blog");  
                    } catch (Exception e) {  
                        e.printStackTrace();  
                    }  
                    try {  
                        String sql = "select id,author,title,content from Blog";  
                        List<News> list_tmp = new ArrayList<News>();  
                        if (conn != null) {  
                            stmt = conn.prepareStatement(sql);  
                            conn.setAutoCommit(false);  
                            ResultSet rs = stmt.executeQuery();//用rs接收sql语句返回的查询结果  
                            //执行查询语句并且保存结果  
                            while (rs.next()) {  
                                Log.d("1", "1");  
                                News news = new News();  
                                news.setId(Integer.parseInt(rs.getString("id")));  
                                news.setAuthor(rs.getString("author"));  
                                news.setTitle(rs.getString("title"));  
                                news.setContent("\u3000\u3000" + rs.getString("content"));  
                                Log.d("Title", news.getTitle());  
                                list_tmp.add(news);  
                            }  
                            Collections.reverse(list_tmp);  
                            sNewsList = list_tmp;  
                            Message msg = new Message();  
                            msg.obj = list_tmp;  
                            handler.sendMessage(msg);  
                            rs.close();  
                        }  
                    } catch (Exception e) {  
                        e.printStackTrace();  
                    } finally {  
                    }  
                }  
            });  
            thread.start();  
            try {  
                thread.join();  
            } catch (InterruptedException e) {  
                e.printStackTrace();  
            }  
            swipeRefreshLayout = (SwipeRefreshLayout) view.findViewById(R.id.swip_refresh);  
            swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener(){  
                @Override  
                public void onRefresh() {  
                    refreshContent();  
                }  
            });  
            newsAdapter.setmNewList(sNewsList);  
            Log.d("length:", String.valueOf(sNewsList.size()));  
            Log.d(TAG, "What???");  
            newsTitleRecyclerView.setAdapter(newsAdapter);  
            return view;  
        }  
        private void refreshContent() {  
            @SuppressLint("HandlerLeak") final  
            Handler handler = new Handler() {  
                @Override  
                public void handleMessage(Message msg) {  
                    sNewsList = (List<News>) msg.obj;  
    				   newsAdapter.addList(sNewsList);  
                    swipeRefreshLayout.setRefreshing(false);  
                    Log.d("sNewList.length : ", String.valueOf(sNewsList.size()));
                }  
            };  
            Thread thread = null;  
            thread = new Thread(new Runnable() {  
                @Override  
                public void run() {  
                    Log.d(TAG, "ppppp: ???");  
                    try {  
                        Thread.sleep(2000);  
                        conn = MySQLConnections.getConnection("blog");  
                    } catch (Exception e) {  
                        e.printStackTrace();  
                    }  
                    try {  
                        String sql = "select id,author,title,content from Blog";  
                        List<News> list_tmp = new ArrayList<News>();  
                        if (conn != null) {  
                            stmt = conn.prepareStatement(sql);  
                            conn.setAutoCommit(false);  
                            ResultSet rs = stmt.executeQuery();//用rs接收sql语句返回的查询结果  
                            //执行查询语句并且保存结果  
                            while (rs.next()) {  
                                Log.d("1", "1");  
                                News news = new News();  
                                news.setId(Integer.parseInt(rs.getString("id")));  
                                news.setAuthor(rs.getString("author"));  
                                news.setTitle(rs.getString("title"));  
                                news.setContent("\u3000\u3000" + rs.getString("content"));  
                                Log.d("Title", news.getTitle());  
                                list_tmp.add(news);  
                            }  
                            sNewsList = list_tmp;  
                            Message msg = new Message();  
                            msg.obj = list_tmp;  
                            handler.sendMessage(msg);  
                            rs.close();  
                        }  
                    } catch (SQLException e) {  
                        e.printStackTrace();  
                    }  
                }  
            });  
            thread.start();  
       }  
        @Override  
        public void onActivityCreated(@Nullable Bundle savedInstanceState) {  
            super.onActivityCreated(savedInstanceState);  
            if (getActivity().findViewById(R.id.new_content_layout) != null) {  
                isTwoPane = true;  
            } else {  
                isTwoPane = false;  
            }  
        }  
        class NewsAdapter extends RecyclerView.Adapter<NewsAdapter.ViewHolder> {  
            private List<News> mNewsList = new ArrayList<News>();  
            private LayoutInflater mInflater;  
            class ViewHolder extends RecyclerView.ViewHolder {  
                TextView newsTitleText;  
                CardView newsCardView;  
                TextView newsContentPreView;  
                ImageView imageViewPreView;  
                public ViewHolder(View view) {  
                    super(view);  
                    newsCardView = (CardView) view.findViewById(R.id.item_cardview);  
                    newsTitleText = (TextView) view.findViewById(R.id.news_title); 
                    newsContentPreView = (TextView) view.findViewById(R.id.news_contentPre);  
                    imageViewPreView = (ImageView) view.findViewById(R.id.imagePreRandon);  
                }  
            }  
            public NewsAdapter() {  
            }  
            public void setmNewList(List<News> list) {  
                this.mNewsList = list;  
            }  
            @Override  
            public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
                View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.new_item, parent, false);  
                final ViewHolder holder = new ViewHolder(view);  
                view.setOnClickListener(new View.OnClickListener() {  
                    @Override  
                    public void onClick(View v) {  
                        News news = mNewsList.get(holder.getAdapterPosition());  
                        if (isTwoPane) {  
                            NewsContentFragment newsContentFragment = (NewsContentFragment) getFragmentManager()  
                                    .findFragmentById(R.id.news_content_fragment);  
                            newsContentFragment.refresh(news.getTitle(), news.getContent());  
                        } else {  
                            NewsContentActivity.actionStart(getActivity(), news.getTitle(), news.getContent());  
                        }  
                    }  
                });  
                return holder;  
            }  
            @Override  
            public void onBindViewHolder(ViewHolder holder, int position) {  
                News news = mNewsList.get(position);  
                holder.newsTitleText.setText(news.getTitle());  
                holder.newsContentPreView.setText(news.getContent().substring(0, (news.getContent().length() > 10 ? 10 : news.getContent().length() / 2)));  
                int cnt = 1 + new Random().nextInt(11);  
                if (cnt == 1) {  
                    holder.imageViewPreView.setImageResource(R.drawable.img_1);  
               } else if (cnt == 2) {  
                    holder.imageViewPreView.setImageResource(R.drawable.img_2);  
                } else if (cnt == 3) {  
                    holder.imageViewPreView.setImageResource(R.drawable.img_3);  
                } else if (cnt == 4) {  
                    holder.imageViewPreView.setImageResource(R.drawable.img_5);  
                } else if (cnt == 5) {  
                    holder.imageViewPreView.setImageResource(R.drawable.img_5);  
                } else if (cnt == 6) {  
                    holder.imageViewPreView.setImageResource(R.drawable.img_6);  
                } else if (cnt == 7) {  
                    holder.imageViewPreView.setImageResource(R.drawable.img_7);  
                } else if (cnt == 8) {  
                    holder.imageViewPreView.setImageResource(R.drawable.img_8);  
                } else if (cnt == 9) {  
                    holder.imageViewPreView.setImageResource(R.drawable.img_9);  
                } else if (cnt == 10) {  
                    holder.imageViewPreView.setImageResource(R.drawable.img_10);  
                } else if (cnt == 11) {  
                    holder.imageViewPreView.setImageResource(R.drawable.img_11);  
                } else {  
                    holder.imageViewPreView.setImageResource(R.drawable.img_12);  
                }  
            }  
      
            @Override  
            public int getItemCount() {  
                return mNewsList.size();  
            }  
        }  
    }  
    
    
    • 重写onCreateView函数承载每个子项的布局,函数中开启线程和回调函数负责于服务器服务器建立连接MySQLConnections.getConnection("blog"),同时进行select查询;建立SwipeRefreshLayout实现下拉刷新事件。

      onActivityCreated函数判断是平板显示还是手机显示,若是平板显示,则调用帖子内容碎片,否则调用内容活动Activity

      建立内容类适配器NewsAdapter,初始化CardView_item的内容,同时重写onCreateViewHolder函数,负责接收点击CardView_item跳转到帖子详情页面的事件

      重写onBindViewHolder函数承载每个子项Holder绑定数据,函数实现了随机图片显示。swipeRefreshLayout.setOnRefreshListener实现下拉刷新事件,重写OnRefresh函数使用refreshContent函数实现下拉刷新内容数据的更新

      getItemCount函数获取帖子个数

  2. 碎片布局

    <?xml version="1.0" encoding="utf-8"?>  
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
        android:layout_width="match_parent"  
        android:layout_height="match_parent"  
        android:orientation="vertical">  
        <ImageView  
            android:layout_width="match_parent"  
            android:layout_height="match_parent"  
            android:scaleType="centerCrop"  
            android:src="@drawable/bg_wood" />  
        <android.support.v4.widget.SwipeRefreshLayout  
            android:id="@+id/swip_refresh"  
            android:layout_width="match_parent"  
            android:layout_height="match_parent"  
            android:orientation="vertical">  
            <android.support.v7.widget.RecyclerView  
                android:id="@+id/news_title_recycle_view"  
                android:layout_width="match_parent"  
                android:layout_height="match_parent"  
                android:overScrollMode="never" />  
        </android.support.v4.widget.SwipeRefreshLayout>  
    </RelativeLayout> 
    
    • 主页内容碎片采用RelativeLayout布局,标签设置背景图片SwipeRefreshLayout实现下拉刷新RecylarView
  3. RecylerView的子布局

    <android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"  
        xmlns:app="http://schemas.android.com/apk/res-auto"  
        xmlns:card_view="http://schemas.android.com/apk/res-auto"  
        android:layout_width="match_parent"  
        android:layout_height="wrap_content"  
        android:layout_marginBottom="16dp"  
        android:layout_marginLeft="12dp"  
        android:layout_marginRight="12dp"  
        android:layout_marginTop="2dp"  
        app:cardCornerRadius="15dp"  
        app:cardElevation="10dp">  
        <LinearLayout  
            android:layout_width="361dp"  
            android:layout_height="282dp"  
            android:background="#fff"  
            android:orientation="vertical"  
            android:weightSum="1">  
            <ImageView  
                android:id="@+id/imagePreRandon"  
                android:layout_width="match_parent"  
                android:layout_height="182dp"  
                android:scaleType="centerCrop" />  
            <LinearLayout  
                android:layout_width="match_parent"  
                android:layout_height="113dp"  
                android:layout_centerVertical="true"  
                android:layout_margin="12dp"  
                android:orientation="vertical">  
                  <TextView  
                    android:id="@+id/news_title"  
                    android:layout_width="match_parent"  
                    android:layout_height="42dp"  
                    android:padding="5dp"  
                    android:textSize="18sp"  
                    android:textStyle="bold" />  
                <TextView  
                    android:id="@+id/news_contentPre"  
                    android:layout_width="match_parent"  
                    android:layout_height="wrap_content"  
                    android:padding="5dp" />  
            </LinearLayout>  
        </LinearLayout>  
    </android.support.v7.widget.CardView>
    
    • RecyclerView的子view采用CardView布局

侧边栏

  1. Head

    <?xml version="1.0" encoding="utf-8"?>  
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
        xmlns:app="http://schemas.android.com/apk/res-auto"  
        android:layout_width="match_parent"  
        android:layout_height="@dimen/nav_header_height"  
        android:background="@drawable/side_nav_bar"  
        android:gravity="bottom"  
        android:orientation="vertical"  
        android:paddingBottom="@dimen/activity_vertical_margin"  
        android:paddingLeft="@dimen/activity_horizontal_margin"  
        android:paddingRight="@dimen/activity_horizontal_margin"  
        android:paddingTop="@dimen/activity_vertical_margin"  
        android:theme="@style/ThemeOverlay.AppCompat.Dark"  
        android:weightSum="1">  
        <ImageView  
            android:id="@+id/imageView"  
            android:layout_width="match_parent"  
            android:layout_height="88dp"  
            android:paddingTop="@dimen/nav_header_vertical_spacing"  
            android:src="@drawable/touxiang" />  
        <TextView  
            android:layout_width="match_parent"  
            android:layout_height="wrap_content"  
            android:paddingTop="@dimen/nav_header_vertical_spacing"  
            android:text="GaoMing"  
            android:textAppearance="@style/TextAppearance.AppCompat.Body1" />  
        <TextView  
            android:id="@+id/textView"  
            android:layout_width="wrap_content"  
            android:layout_height="wrap_content"  
            android:text="所爱山海间"/>  
    </LinearLayout>
    
  2. Menu

    <?xml version="1.0" encoding="utf-8"?>  
    <menu xmlns:android="http://schemas.android.com/apk/res/android">  
        <group android:checkableBehavior="single">  
            <item  
                android:id="@+id/nav_camera"  
                android:icon="@drawable/ic_menu_camera"  
                android:title="登录" />  
            <item  
                android:id="@+id/nav_gallery"  
                android:icon="@drawable/ic_menu_gallery"  
                android:title="发帖" />  
            <item  
                android:id="@+id/nav_slideshow"  
                android:icon="@drawable/ic_menu_slideshow"  
                android:title="GaoMing’s Web " />  
            <item  
                android:id="@+id/nav_manage"  
                android:icon="@drawable/ic_menu_manage"  
                android:title="地图
     " />  
        </group>  
        <item android:title="Communicate">  
            <menu>  
                <item  
                    android:id="@+id/nav_share"  
                    android:icon="@drawable/ic_menu_share"  
                    android:title="Share" />  
                <item  
                    android:id="@+id/nav_send"  
                    android:icon="@drawable/ic_menu_send"  
                    android:title="Send" />  
            </menu>  
        </item>  
    </menu>  
    

帖子详情页面

  1. 活动核心代码

    public class NewsContentActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener {  
        private ImageView imageViewContent;  
        public static void actionStart(Context context, String newsTitle, String newsContent) {  
            Intent intent = new Intent(context, NewsContentActivity.class);  
            intent.putExtra("news_title", newsTitle);  
            intent.putExtra("news_content", newsContent);  
            context.startActivity(intent);  
        }  
        @Override  
        protected void onCreate(Bundle savedInstanceState) {  
            super.onCreate(savedInstanceState);  
            setContentView(R.layout.activity_news_content);  
            imageViewContent = (ImageView) findViewById(R.id.imageContent);  
            int cnt = 1 + new Random().nextInt(11);  
            if (cnt == 1) {  
                imageViewContent.setImageResource(R.drawable.img_1);  
            } else if (cnt == 2) {  
                imageViewContent.setImageResource(R.drawable.img_2);  
            } else if (cnt == 3) {  
                imageViewContent.setImageResource(R.drawable.img_3);  
            } else if (cnt == 4) {  
                imageViewContent.setImageResource(R.drawable.img_5);  
            } else if (cnt == 5) {  
                imageViewContent.setImageResource(R.drawable.img_5);  
            } else if (cnt == 6) {  
                imageViewContent.setImageResource(R.drawable.img_6);  
            } else if (cnt == 7) {  
                imageViewContent.setImageResource(R.drawable.img_7);  
            } else if (cnt == 8) {  
                imageViewContent.setImageResource(R.drawable.img_8);  
            } else if (cnt == 9) {  
                imageViewContent.setImageResource(R.drawable.img_9);  
            } else if (cnt == 10) {  
                imageViewContent.setImageResource(R.drawable.img_10);  
            } else if (cnt == 11) {  
                imageViewContent.setImageResource(R.drawable.img_11);  
            } else {  
                imageViewContent.setImageResource(R.drawable.img_12);  
            }  
            Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);  
            String newsTitle = getIntent().getStringExtra("news_title");  
            String newContent = getIntent().getStringExtra("news_content");  
            NewsContentFragment newsContentFragment = (NewsContentFragment) getSupportFragmentManager()  
                    .findFragmentById(R.id.news_content_fragment);  
            newsContentFragment.refresh(newsTitle, newContent);  
            toolbar.setTitle(newsTitle);  
            toolbar.setSubtitle(newsTitle);  
            setSupportActionBar(toolbar);  
            getSupportActionBar().setDisplayHomeAsUpEnabled(true);//左侧添加一个默认的返回图标  
            getSupportActionBar().setHomeButtonEnabled(true); //设置返回键可用  
            toolbar.setNavigationOnClickListener(new View.OnClickListener() {  
                @Override  
                public void onClick(View v) {  
                    finish();  
                }  
            });  
        }  
        @Override  
        public boolean onNavigationItemSelected(@NonNull MenuItem item) {  
            return false;  
        }  
    }  
    
    • actionStart函数负责启动活动,onCreate生成活动窗口,初始化内容。
  2. 帖子详情页面布局

    <?xml version="1.0" encoding="utf-8"?>  
    <android.support.design.widget.CoordinatorLayout 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"  
        android:orientation="vertical">  
        <android.support.design.widget.AppBarLayout  
            android:layout_width="match_parent"  
            android:layout_height="200dp">  
            <android.support.design.widget.CollapsingToolbarLayout  
                android:id="@+id/toolbar_layout"  
                android:layout_width="match_parent"  
                android:layout_height="match_parent"  
                app:contentScrim="@color/colorPrimary"  
                app:layout_scrollFlags="scroll|exitUntilCollapsed">  
                <ImageView  
                    android:id="@+id/imageContent"  
                    android:layout_width="match_parent"  
                    android:layout_height="match_parent"  
                    android:scaleType="centerCrop"  
                    app:layout_collapseMode="parallax"  
                    app:layout_collapseParallaxMultiplier="0.9"  
                    tools:ignore="ContentDescription" />  
                <android.support.v7.widget.Toolbar  
                    android:id="@+id/toolbar"  
                    android:layout_width="match_parent"  
                    android:layout_height="50dp"  
                    android:theme="@style/ToolBarTheme"  
                    app:layout_collapseMode="pin" />  
            </android.support.design.widget.CollapsingToolbarLayout>  
        </android.support.design.widget.AppBarLayout>  
        <android.support.v4.widget.NestedScrollView  
            android:id="@+id/visibility_layout"  
            android:layout_width="match_parent"  
            android:layout_height="match_parent"  
            app:layout_behavior="@string/appbar_scrolling_view_behavior">  
            <android.support.v7.widget.CardView  
                android:layout_width="match_parent"  
                android:layout_height="match_parent"  
                android:layout_marginBottom="15dp"  
                android:layout_marginLeft="15dp"  
                android:layout_marginRight="15dp"  
                android:layout_marginTop="15dp"  
                app:cardCornerRadius="10dp"  
                app:cardElevation="10dp">  
                <TextView  
                    android:id="@+id/news_content"  
                    android:layout_width="match_parent"  
                    android:layout_height="match_parent"  
                    android:layout_gravity="center_horizontal"  
                    android:textSize="20sp" />  
            </android.support.v7.widget.CardView>  
        </android.support.v4.widget.NestedScrollView>  
    </android.support.design.widget.CoordinatorLayout>
    
    • 内容布局采用CoordinatorLayout(Super-power FrameLayout)作为顶部布局和同时负责协调子view交互。使用AppBarLayout响应滚动手势和ToorBar**作为顶部子项。使用CardView作为帖子详细内容主体。

发布帖子页面

  1. PublishPost核心代码

    public class PublishPost extends AppCompatActivity {  
        private Uri imageUri;  
        private static int number = 0;  
        private ImageView imageView;  
        private EditText editText1;  
        private EditText editText2;  
        private EditText editText3;  
        private Toolbar toolbar;  
        private Button button;  
        private final int CODE_PICK_PHOTO = 0;  
        private final int RESULT_REQUEST_CODE = -1;  
        private String bitmapToString= null;  
        private String photoPath = null;  
        private Bitmap bitmap;  
        private String username;  
        @Override  
        protected void onCreate(Bundle savedInstanceState) {  
            super.onCreate(savedInstanceState);  
            setContentView(R.layout.activity_publish_post);  
            Intent intentRec = getIntent();  
            username = intentRec.getStringExtra("userName");  
            Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);  
            final Handler handler = new Handler(new Handler.Callback() {  
                @Override  
                public boolean handleMessage(Message message) {  
                    return false;  
                }  
            });  
            new Thread(new Runnable() {  
                @Override  
                public void run() {  
                    Message msg = new Message();//message用于给handler传递参数  
                    try {  
                        MySQLConnections.getConnection("Blog");  
                    } catch (Exception e) {  
                        e.printStackTrace();  
                        Log.d("TAG", " 数据操作异常");  
                    }  
                    handler.sendMessage(msg);  
               }  
            }).start();  
            imageView = (ImageView) findViewById(R.id.imageUp);  
            imageView.setOnClickListener(new View.OnClickListener() {  
                @Override  
                public void onClick(View v) {  
                    Intent intent_gallery = new Intent(Intent.ACTION_PICK);  
                    intent_gallery.setType("image/*");  
                    startActivityForResult(intent_gallery, CODE_PICK_PHOTO);  
                }  
            });  
            editText1 = (EditText) findViewById(R.id.upAuthor);  
            editText2 = (EditText) findViewById(R.id.uptitle);  
            editText3 = (EditText) findViewById(R.id.upcontent);  
            button = (Button) findViewById(R.id.buttonPub);  
            button.setOnClickListener(new View.OnClickListener() {  
                @Override  
                public void onClick(View v) {  
                    final String title = editText1.getText().toString();  
                    final String author = editText2.getText().toString();  
                    final String content = editText3.getText().toString();  
                    new Thread(new Runnable() {  
                        @Override  
                        public void run() {  
                            try {  
                                MySQLConnections.insertIntoData(PublishPost.number++, title, author, content,bitmapToString);//调用插入数据库语句  
                            } catch (SQLException e) {  
                                e.printStackTrace();  
                            }  
                        }  
                    }).start();  
                    Saving(title,content,username,bitmapToString);  
                    Intent intent = new Intent(PublishPost.this, MainActivity.class);  
                    intent.putExtra("postTitle",title);  
                    intent.putExtra("UNAME",username);  
                    setResult(RESULT_OK, intent);  
                    finish();  
                }  
            });  
            toolbar = (Toolbar) findViewById(R.id.toolbarPub);  
            toolbar.setTitle("发帖");  
            toolbar.setSubtitle("GaoMing");  
            setSupportActionBar(toolbar);  
            getSupportActionBar().setDisplayHomeAsUpEnabled(true);  
            getSupportActionBar().setHomeButtonEnabled(true);  
            toolbar.setNavigationOnClickListener(new View.OnClickListener() {  
                @Override  
                public void onClick(View v) {  
                    finish();  
                }  
            });  
        }  
      
       private void Saving(String title, String content, String username, String bitmapToString) {  
            MyPost mypost = new MyPost();  
            mypost.setNewstitle(title);  
            mypost.setNewscontent(content);  
            mypost.setUsername(username);  
            mypost.setImagePost(bitmapToString);  
            boolean is_ok = mypost.save();  
            Log.d("Answer:",String.valueOf(is_ok));  
        }  
      
        @Override  
        protected void onActivityResult(int requestCode, int resultCode, Intent data) {  
            super.onActivityResult(requestCode, resultCode, data);  
            if (requestCode == CODE_PICK_PHOTO) {//相册  
                imageUri= data.getData();  
                //获取照片路径  
                imageView.setImageURI(imageUri);  
                Bitmap bitmap = null;  
                try {  
                    bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), imageUri);  
                    bitmapToString = ImageHelper.bitmapToString(bitmap);  
                } catch (IOException e) {  
                    e.printStackTrace();  
                }  
            }  
        }  
      
    }  
    
    • onCreate函数初始化发帖活动和布局,同时开启线程连接服务器的数据库(MySQLonActivityResult函数处理图片解析,将图片解析成字符串并保存到数据库。点击发布按钮,触发开启线程插入帖子到数据库MySQLConnections.insertIntoData)。
  2. PublishPost布局

    <?xml version="1.0" encoding="utf-8"?>  
    <LinearLayout 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"  
        android:orientation="vertical"  
        tools:context="cn.com.text.Activity.PublishPost">  
        <android.support.design.widget.AppBarLayout  
            android:layout_width="match_parent"  
            android:layout_height="wrap_content"  
            android:theme="@style/AppTheme.NoActionBar.AppBarOverlay">  
            <android.support.v7.widget.Toolbar  
                android:id="@+id/toolbarPub"  
                android:layout_width="match_parent"  
                android:layout_height="?attr/actionBarSize"  
                android:background="?attr/colorPrimary"  
                app:popupTheme="@style/AppTheme.NoActionBar.PopupOverlay" />  
        </android.support.design.widget.AppBarLayout>  
        <LinearLayout  
            android:layout_width="match_parent"  
            android:layout_height="wrap_content"  
            android:orientation="vertical">  
            <Button  
                android:id="@+id/buttonPub"  
                android:layout_width="match_parent"  
                android:layout_height="wrap_content"  
                android:text="发布" />  
        </LinearLayout>  
        <LinearLayout  
            android:layout_width="368dp"  
            android:layout_height="wrap_content"  
            android:orientation="vertical"></LinearLayout>  
        <include  
            android:id="@+id/include"  
            layout="@layout/content_publish_post"  
            android:layout_width="wrap_content"  
            android:layout_height="429dp" />  
    </LinearLayout>  
    

WebBlog

  1. 此模块使用WebView实现APP内嵌网页,网页链接到我的个人博客(GaoMing’s Web),并且添加ToolBar作为顶部,添加返回键。

    public class WebBlog extends AppCompatActivity {  
        private Toolbar toolbar;  
        @Override  
        protected void onCreate(Bundle savedInstanceState) {  
            super.onCreate(savedInstanceState);  
            setContentView(R.layout.activity_web_blog);  
            toolbar = (Toolbar) findViewById(R.id.toolbarWeb);  
            toolbar.setTitle("Blog");  
            toolbar.setSubtitle("GaoMing");  
            setSupportActionBar(toolbar);  
    //        toolbar.setNavigationIcon(R.drawable.ic_action_n);  
            getSupportActionBar().setDisplayHomeAsUpEnabled(true);//左侧添加一个默认的返回图标  
            getSupportActionBar().setHomeButtonEnabled(true); //设置返回键可用  
            toolbar.setNavigationOnClickListener(new View.OnClickListener() {  
                @Override  
                public void onClick(View v) {  
                    finish();  
                }  
            });  
            WebView webView = (WebView) findViewById(R.id.web_view);  
            webView.getSettings().setJavaScriptEnabled(true);  
            webView.setWebViewClient(new WebViewClient());  
            webView.loadUrl("http://www.keegan.cn");  
        }  
    }  
    

登录功能

  1. 登录活动实现用户登录和注册,否则用户只有看帖操作,无发帖删帖更新帖子的操作。后台获取到usernamepassword,会进行验证是否为空,根据点击的按钮触发注册或者登录,如果是注册,会查询数据库是否已存在该用户,没有的话就进行插入操作,如果是点击登录,会查询数据库是否存在该用户,如果存在,则跳转登录到主页,否则弹出不存在该用户的Toast提示。对于头像上传,要求注册时必须选择头像,否则会注册失败。

    public class LogActivity extends AppCompatActivity {  
        private Button button_submit;  
        private EditText username;  
        private EditText password;  
        private Button button_reg;  
        private ImageView imageView;  
        private final int CODE_PICK_PHOTO = 1;  
        private Uri imageUri;  
        private String bitmapToString = null;  
        @Override  
        protected void onCreate(Bundle savedInstanceState) {  
            super.onCreate(savedInstanceState);  
            setContentView(R.layout.activity_log);  
            LitePal.getDatabase();  
            username = (EditText) findViewById(R.id.username);  
            password = (EditText) findViewById(R.id.password);  
            imageView = (ImageView) findViewById(R.id.userImage);  
            imageView.setOnClickListener(new View.OnClickListener() {  
                @Override  
                public void onClick(View v) {  
                    Intent intent_gallery = new Intent(Intent.ACTION_PICK);  
                    intent_gallery.setType("image/*");  
                    startActivityForResult(intent_gallery, CODE_PICK_PHOTO);  
               }  
            });  
            button_submit = (Button) findViewById(R.id.button_submit);  
            button_submit.setOnClickListener(new View.OnClickListener() {  
                @Override  
                public void onClick(View v) {  
                    if ((!TextUtils.isEmpty(username.getText()) && (!TextUtils.isEmpty(password.getText())))) {  
                        User usr = new User();  
                        usr.setName(username.getText().toString());  
                        usr.setPassword(password.getText().toString());  
                        usr.setImage(bitmapToString);  
                        //检查是否有此用户  
                        List<User> userList = DataSupport.where("name = ? and password = ?", usr.getName(),usr.getPassword()).find(User.class);  
                        if (userList.isEmpty()) {  
                            Toast.makeText(LogActivity.this, "用户名或密码错误", Toast.LENGTH_SHORT).show();  
                        } else {  
                            Log.d("username", username.getText().toString());  
                            Toast.makeText(LogActivity.this, "登陆成功", Toast.LENGTH_SHORT).show();  
                            Intent intent = new Intent(LogActivity.this, MainActivity.class);  
                            intent.putExtra("username",usr.getName());  
                            intent.putExtra("password",usr.getPassword());  
                           // intent.putExtra("image",bitmapToString);  
                            setResult(RESULT_OK,intent);  
                            finish();  
                        }  
                    }else {  
                        Toast.makeText(LogActivity.this,"用户名或密码不为空",Toast.LENGTH_SHORT).show();  
                    }  
                }  
            });  
            button_reg = (Button) findViewById(R.id.reg_button);  
            button_reg.setOnClickListener(new View.OnClickListener() {  
                @Override  
                public void onClick(View v) {  
                    if ((!TextUtils.isEmpty(username.getText()) && (!TextUtils.isEmpty(password.getText())))) {  
                        final User usr = new User();  
                        final String usrname = username.getText().toString();  
                        final String usrpassword = password.getText().toString();  
                        usr.setName(usrname);  
                        usr.setPassword(usrpassword);  
                        usr.setImage(bitmapToString);  
                        //检查是否有此用户  
                        List<User> userList = DataSupport.where("name = ?", usr.getName()).find(User.class);  
                        if(bitmapToString != null){  
                            if (userList.isEmpty()) {  
                                Thread thread = null;  
                                thread = new Thread(new Runnable() {  
                                    @Override  
                                    public void run() {  
                                        try {  
                                            MySQLConnections.insertIntoUser(usrname,usrpassword,bitmapToString);  
                                        } catch (SQLException e) {  
                                            e.printStackTrace();  
                                        }  
                                    }  
                                });  
                                thread.start();  
                                try {  
                                    thread.join();  
                                }catch (Exception e){  
                                    e.printStackTrace();  
                                }  
                                usr.save();  
                                Toast.makeText(LogActivity.this, "注册成功", Toast.LENGTH_SHORT).show();  
                            } else {  
                                Toast.makeText(LogActivity.this, "重复注册,请登录", Toast.LENGTH_SHORT).show();  
                            }  
                        }else {  
                            Toast.makeText(LogActivity.this,"请选择头像",Toast.LENGTH_SHORT).show();  
                        }  
      
                    }else{  
                        Toast.makeText(LogActivity.this,"注册用户名或密码不为空",Toast.LENGTH_SHORT).show();  
                    }  
                }  
            });  
        }  
      
        @Override  
        protected void onActivityResult(int requestCode, int resultCode, Intent data) {  
            super.onActivityResult(requestCode, resultCode, data);  
            if (requestCode == CODE_PICK_PHOTO) {//相册  
                imageUri= data.getData();  
                //获取照片路径  
                imageView.setImageURI(imageUri);  
                Bitmap bitmap = null;  
                try {  
                    bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), imageUri);  
                    bitmapToString = ImageHelper.bitmapToString(bitmap);  
                } catch (IOException e) {  
                    e.printStackTrace();  
                }  
            }  
        }  
    }  
    
  2. 登录页面布局

    <?xml version="1.0" encoding="utf-8"?>  
    <LinearLayout 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:id="@+id/activity_main"  
        android:layout_width="match_parent"  
        android:layout_height="match_parent"  
        android:orientation="vertical"  
        android:paddingBottom="@dimen/activity_vertical_margin"  
        android:paddingLeft="@dimen/activity_horizontal_margin"  
        android:paddingRight="@dimen/activity_horizontal_margin"  
        android:paddingTop="@dimen/activity_vertical_margin"  
        android:weightSum="1"  
        tools:context="cn.com.text.Activity.LogActivity">  
        <LinearLayout  
            android:layout_width="wrap_content"  
            android:layout_height="133dp"  
            android:layout_weight="0.02"  
            android:orientation="vertical">  
            <ImageView  
                android:id="@+id/userImage"  
                android:layout_width="match_parent"  
                android:layout_height="wrap_content"  
                android:layout_gravity="center_horizontal"  
                app:srcCompat="@drawable/touxiang" />  
        </LinearLayout>  
        <LinearLayout  
            android:layout_width="match_parent"  
            android:layout_height="16dp"  
            android:orientation="vertical"></LinearLayout>  
        <LinearLayout  
            android:layout_width="match_parent"  
            android:layout_height="76dp">  
            <TextView  
                android:layout_width="wrap_content"  
                android:layout_height="match_parent"  
                android:text="账户:" />  
            <EditText  
                android:id="@+id/username"  
                android:layout_width="match_parent"  
                android:layout_height="match_parent" />  
        </LinearLayout>  
        <LinearLayout  
            android:layout_width="match_parent"  
            android:layout_height="76dp">  
            <TextView  
                android:layout_width="wrap_content"  
                android:layout_height="match_parent"  
                android:text="密码:" />  
            <EditText  
                android:id="@+id/password"  
                android:layout_width="match_parent"  
                android:layout_height="match_parent" />  
        </LinearLayout>  
        <Button  
            android:id="@+id/button_submit"  
            android:layout_width="match_parent"  
            android:layout_height="69dp"  
            android:text="登录" />  
        <Button  
            android:id="@+id/reg_button"  
            android:layout_width="match_parent"  
            android:layout_height="69dp"  
            android:text="注册" />  
    </LinearLayout> 
    

用户中心页面

  1. MyPostActivity实现用户信息显示和已发帖显示,支持点击查看帖子详情和修改删除该贴。实现过程如下:从MainActivity传输的intent中获取当前登录的用户名,查询数据库MyPost表,用户发过的帖子经过PublishPost都已经保存了,所以此时读取到数据后,使用适配器填充ListView的内容显示出来,增加onItem点击事件跳转到其他页面或者选择删除该贴。

    public class MyPostActivity extends AppCompatActivity {  
        private List<MyPost> mypost = new ArrayList<MyPost>();  
        private String username = null;  
        private ImageView imageView;  
        private String imageBit = "";  
        @Override  
        protected void onCreate(Bundle savedInstanceState) {  
            super.onCreate(savedInstanceState);  
            setContentView(R.layout.activity_my_post);  
            Intent intent = getIntent();  
            username = intent.getStringExtra("userName");  
            imageView = (ImageView) findViewById(R.id.imageUserTouxiang);  
            List<User> userList = DataSupport.where("name = ?", username).find(User.class);  
            if (userList.size() != 0) {  
                imageBit = userList.get(0).getImage();  
            }  
            if (imageBit.equals("")) {  
                imageView.setImageResource(R.drawable.touxiang);  
            } else {  
                imageView.setImageBitmap(ImageHelper.stringToBitmap(imageBit));  
            }  
            initMyPost();  
            MyPostAdapter myPostAdapter = new MyPostAdapter(MyPostActivity.this, R.layout.mypost_item, mypost);  
            ListView listview = (ListView) findViewById(R.id.list_MyPost);  
            listview.setAdapter(myPostAdapter);  
            listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {  
                @Override  
                public void onItemClick(AdapterView<?> parent, View view, final int position, long id) {  
                    final MyPost post = mypost.get(position);  
                    showNormalDialog(position);  
    //                Intent intent = new Intent(MyPostActivity.this,NewsContentActivity.class);  
    //                intent.putExtra("news_title", post.getNewstitle());  
    //                intent.putExtra("news_content", post.getNewscontent());  
    //                startActivity(intent);  
                }  
            });  
        }  
      
        private void initMyPost() {  
            mypost = DataSupport.where("username = ?", username).find(MyPost.class);  
        }  
        private void showNormalDialog(final int position) {  
            //创建dialog构造器  
            AlertDialog.Builder normalDialog = new AlertDialog.Builder(this);  
            //设置title  
            normalDialog.setTitle("选择");  
            //设置内容  
            normalDialog.setMessage("你确定这样做么?");  
            //设置按钮  
            normalDialog.setPositiveButton("查看"  
                    , new DialogInterface.OnClickListener() {  
                        @Override  
                        public void onClick(DialogInterface dialog, int which) {  
                            final MyPost post = mypost.get(position);  
                            Intent intent = new Intent(MyPostActivity.this, NewsContentActivity.class);  
                            intent.putExtra("news_title", post.getNewstitle());  
                            intent.putExtra("news_content", post.getNewscontent());  
                            startActivity(intent);  
                            dialog.dismiss();  
                        }  
                    });  
            normalDialog.setNegativeButton("更改",  
                    new DialogInterface.OnClickListener() {  
                        @Override  
                        public void onClick(DialogInterface dialog, int which) {  
                            final MyPost post = mypost.get(position);  
                            Intent intent = new Intent(MyPostActivity.this, UpdataPost.class);  
                            intent.putExtra("username", username);  
                            intent.putExtra("title", post.getNewstitle());  
                            intent.putExtra("content", post.getNewscontent());  
                            startActivity(intent);  
                        }  
                    });  
            //创建并显示  
            normalDialog.create().show();  
        }  
    }  
    
    • 用户帖子适配器

      public class MyPostAdapter extends ArrayAdapter<MyPost>{  
          private int rescoureId;  
          public MyPostAdapter(Context context, int textViewResourceId, List<MyPost> objects) {  
              super(context,textViewResourceId,objects);  
              this.rescoureId = textViewResourceId;  
          }  
        
          @NonNull  
          @Override  
          public View getView(int position, View convertView, ViewGroup parent) {  
              MyPost myPost = getItem(position);  
              View view = LayoutInflater.from(getContext()).inflate(rescoureId,parent,false);  
              ImageView imageView = (ImageView) view.findViewById(R.id.imageViewMyPost);  
              TextView postTitle = (TextView) view.findViewById(R.id.textViewTitle);  
              TextView postContent = (TextView) view.findViewById(R.id.textViewContent);  
              imageView.setImageBitmap(ImageHelper.stringToBitmap(myPost.getImagePost()));  
              postTitle.setText(myPost.getNewstitle());  
              postContent.setText(myPost.getNewscontent());  
              return view;  
          }  
      }  
      
  2. 用户中心页面布局

    <?xml version="1.0" encoding="utf-8"?>  
    <android.support.design.widget.CoordinatorLayout 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"  
        android:orientation="vertical">  
        <android.support.design.widget.AppBarLayout  
            android:layout_width="match_parent"  
            android:layout_height="200dp">  
            <android.support.design.widget.CollapsingToolbarLayout  
                android:id="@+id/toolbar_layout1"  
                android:layout_width="match_parent"  
                android:layout_height="match_parent"  
                app:contentScrim="@color/colorPrimary"  
                app:layout_scrollFlags="scroll|exitUntilCollapsed">  
                <ImageView  
                    android:id="@+id/imageUserTouxiang"  
                    android:layout_width="match_parent"  
                    android:layout_height="match_parent"  
                    android:scaleType="centerCrop"  
                    app:layout_collapseMode="parallax"  
                    app:layout_collapseParallaxMultiplier="0.9"  
                    tools:ignore="ContentDescription" />  
                <android.support.v7.widget.Toolbar  
                    android:id="@+id/toolbar"  
                    android:layout_width="match_parent"  
                    android:layout_height="50dp"  
                    android:theme="@style/ToolBarTheme"  
                    app:layout_collapseMode="pin" />  
            </android.support.design.widget.CollapsingToolbarLayout>  
        </android.support.design.widget.AppBarLayout>  
        <android.support.v4.widget.NestedScrollView  
            android:id="@+id/visibility_layout"  
            android:layout_width="match_parent"  
            android:layout_height="match_parent"  
            android:fillViewport="true"  
            app:layout_behavior="@string/appbar_scrolling_view_behavior">  
            <ListView  
                android:id="@+id/list_MyPost"  
                android:layout_width="match_parent"  
                android:layout_height="match_parent"></ListView>  
        </android.support.v4.widget.NestedScrollView>  
    </android.support.design.widget.CoordinatorLayout> 
    
    • 用户页面List子布局

      <?xml version="1.0" encoding="utf-8"?>  
      <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
          xmlns:app="http://schemas.android.com/apk/res-auto"  
          android:layout_width="match_parent"  
          android:layout_height="100dp">  
          <ImageView  
              android:id="@+id/imageViewMyPost"  
              android:layout_width="100dp"  
              android:layout_height="match_parent"  
              app:srcCompat="@color/Blue" />  
          <LinearLayout  
              android:layout_width="match_parent"  
              android:layout_height="match_parent"  
              android:orientation="horizontal">  
              <LinearLayout  
                  android:layout_width="match_parent"  
                  android:layout_height="match_parent"  
                  android:orientation="vertical"  
                  android:weightSum="1">  
                  <TextView  
                      android:id="@+id/textViewTitle"  
                      android:layout_width="match_parent"  
                      android:layout_height="50dp"  
                      android:gravity="center_horizontal"  
                      android:text="TextView" />  
                  <LinearLayout  
                      android:layout_width="match_parent"  
                      android:layout_height="wrap_content"  
                      android:orientation="horizontal">  
                      <TextView  
                          android:id="@+id/textViewContent"  
                          android:layout_width="match_parent"  
                          android:layout_height="match_parent"  
                          android:layout_weight="1"  
                          android:gravity="center_horizontal"  
                          android:text="TextView" />  
                  </LinearLayout>  
              </LinearLayout>  
          </LinearLayout>  
      </LinearLayout>
      

地图

借助高德地图API开发包,参考博客

  1. 该模块借助高德地图开发包,实现APP内嵌地图和定位,查找地区等功能。

    进入活动后,首先请求获取相应权限,获取成功后,调用initLocation初始化位置以及调用initMap初始化地图,根据用户位置,调用updateMapCenter使得相机视角转到用户位置。同时设计短时点击和长按点击监听事件,优化用户体验。搜索地址实现原理是获取到输入的内容,搜索位置,得到经纬度,随后调用updateMapCenter使得视角转向地址。

  2. 核心代码

 public class MapActivity extends AppCompatActivity implements  
         AMapLocationListener, LocationSource,  
         PoiSearch.OnPoiSearchListener, AMap.OnMapClickListener, AMap.OnMapLongClickListener,  
         GeocodeSearch.OnGeocodeSearchListener, EditText.OnKeyListener {  
     //输入框  
     private EditText etAddress;  
     //城市  
     private String city;  
     //地理编码搜索  
     private GeocodeSearch geocodeSearch;  
     //解析成功标识码  
     private static final int PARSE_SUCCESS_CODE = 1000;  
     //POI查询对象  
     private PoiSearch.Query query;  
     //POI搜索对象  
     private PoiSearch poiSearch;  
     //城市码  
     private String cityCode = null;  
     //浮动按钮  
     private FloatingActionButton fabPOI;  
     //定义一个UiSettings对象  
     private UiSettings mUiSettings;  
     //定位样式  
     private MyLocationStyle myLocationStyle = new MyLocationStyle();  
     //地图控制器  
     private AMap aMap = null;  
     //位置更改监听  
     private OnLocationChangedListener mListener;  
     private MapView mapView;  
     private static final int REQUEST_PERMISSIONS = 9527;  
     //声明AMapLocationClient类对象  
     public AMapLocationClient mLocationClient = null;  
     //声明AMapLocationClientOption对象  
     public AMapLocationClientOption mLocationOption = null;  
     private Toolbar toolbar;  
     @Override  
     protected void onCreate(Bundle savedInstanceState) {  
         super.onCreate(savedInstanceState);  
         setContentView(R.layout.activity_map);  
         ServiceSettings.updatePrivacyShow(this, true, true);  
         ServiceSettings.updatePrivacyAgree(this, true);  
         toolbar = (Toolbar) findViewById(R.id.toolbarMap);  
         toolbar.setTitle("地图");  
         setSupportActionBar(toolbar);  
 //        toolbar.setNavigationIcon(R.drawable.ic_action_n);  
         getSupportActionBar().setDisplayHomeAsUpEnabled(true);//左侧添加一个默认的返回图标  
         getSupportActionBar().setHomeButtonEnabled(true); //设置返回键可用  
         toolbar.setNavigationOnClickListener(new View.OnClickListener() {  
             @Override  
             public void onClick(View v) {  
                 finish();  
             }  
         });  
         fabPOI = (FloatingActionButton) findViewById(R.id.fab_poi);  
         etAddress = (EditText) findViewById(R.id.et_address);  
         etAddress.setOnKeyListener(this);  
         mapView = (MapView) findViewById(R.id.map_view);  
         mapView.onCreate(savedInstanceState);  
         initLocation();  
         try {  
             initMap(savedInstanceState);  
         } catch (AMapException e) {  
             e.printStackTrace();  
         }  
         checkingAndroidVersion();  
     }  
     /** 
      * 检查Android版本 
      */  
     private void checkingAndroidVersion() {  
         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {  
             //Android6.0及以上先获取权限再定位  
             requestPermission();  
         } else {  
             //Android6.0以下直接定位  
             mLocationClient.startLocation();  
         }  
     }  
     @AfterPermissionGranted(REQUEST_PERMISSIONS)  
     private void requestPermission() {  
         String[] permissions = {  
                 Manifest.permission.ACCESS_COARSE_LOCATION,  
                 Manifest.permission.ACCESS_FINE_LOCATION,  
                 Manifest.permission.READ_PHONE_STATE,  
                 Manifest.permission.WRITE_EXTERNAL_STORAGE  
         };  
         if (EasyPermissions.hasPermissions(this, permissions)) {  
             //true 有权限 开始定位  
             showMsg("已获得权限,可以定位啦!");  
             mLocationClient.startLocation();  
         } else {  
             //false 无权限  
             EasyPermissions.requestPermissions(this, "需要权限", REQUEST_PERMISSIONS, permissions);  
         }  
     }  
     /** 
      * 请求权限结果 
      * 
      * @param requestCode 
      * @param permissions 
      * @param grantResults 
      */  
     @Override  
     public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {  
         super.onRequestPermissionsResult(requestCode, permissions, grantResults);  
         //设置权限请求结果  
         EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this);  
     }  
     /** 
      * 初始化定位 
      */  
     private void initLocation() {  
         //初始化定位  
         try {  
             mLocationClient = new AMapLocationClient(getApplicationContext());  
         } catch (Exception e) {  
             e.printStackTrace();  
         }  
         //设置定位回调监听  
         mLocationClient.setLocationListener(this);  
         //初始化AMapLocationClientOption对象  
         mLocationOption = new AMapLocationClientOption();  
         //设置定位模式为AMapLocationMode.Hight_Accuracy,高精度模式。  
         mLocationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);  
         //获取最近3s内精度最高的一次定位结果:  
         //设置setOnceLocationLatest(boolean b)接口为true,启动定位时SDK会返回最近3s内精度最高的一次定位结果。如果设置其为true,setOnceLocation(boolean b)接口也会被设置为true,反之不会,默认为false。  
         mLocationOption.setOnceLocationLatest(true);  
         //设置是否返回地址信息(默认返回地址信息)  
         mLocationOption.setNeedAddress(true);  
         //设置定位请求超时时间,单位是毫秒,默认30000毫秒,建议超时时间不要低于8000毫秒。  
         mLocationOption.setHttpTimeOut(20000);  
         //关闭缓存机制,高精度定位会产生缓存。  
         mLocationOption.setLocationCacheEnable(false);  
         //给定位客户端对象设置定位参数  
         mLocationClient.setLocationOption(mLocationOption);  
     }  
     private void showMsg(String s) {  
         Toast.makeText(MapActivity.this, s, Toast.LENGTH_SHORT).show();  
     }  
     @Override  
     public void onLocationChanged(AMapLocation aMapLocation) {  
         if (aMapLocation != null) {  
             if (aMapLocation.getErrorCode() == 0) {  
                 //地址  
                 String address = aMapLocation.getAddress();  
                 double latitude = aMapLocation.getLatitude();  
                 double longitude = aMapLocation.getLongitude();  
                 StringBuffer stringBuffer = new StringBuffer();  
                 stringBuffer.append("纬度:" + latitude + "\n");  
                 stringBuffer.append("经度:" + longitude + "\n");  
                 stringBuffer.append("地址:" + address + "\n");  
                 Log.d("MapActivity:", stringBuffer.toString());  
                 if (mListener != null) {  
                     mListener.onLocationChanged(aMapLocation);  
                 }  
                 mLocationClient.stopLocation();  
                 //显示浮空按钮  
                 fabPOI.show();  
                 //赋值  
                 cityCode = aMapLocation.getCityCode();  
                 //城市赋值  
                 city = aMapLocation.getCity();  
                 updateMapCenter(new LatLng(latitude, longitude));  
             } else {  
                 //定位失败时,可通过ErrCode(错误码)信息来确定失败的原因,errInfo是错误信息,详见错误码表。  
                 Log.e("AmapError", "location Error, ErrCode:"  
                         + aMapLocation.getErrorCode() + ", errInfo:"  
                         + aMapLocation.getErrorInfo());  
             }  
         }  
     }  
     @Override  
     protected void onDestroy() {  
         super.onDestroy();  
         //销毁定位客户端,同时销毁本地定位服务。  
         mLocationClient.onDestroy();  
     }  
     @Override  
     protected void onResume() {  
         super.onResume();  
         //在activity执行onResume时执行mMapView.onResume (),重新绘制加载地图  
         mapView.onResume();  
     }  
     @Override  
     protected void onPause() {  
         super.onPause();  
         //在activity执行onPause时执行mMapView.onPause (),暂停地图的绘制  
         mapView.onPause();  
     }  
     @Override  
     protected void onSaveInstanceState(Bundle outState) {  
         super.onSaveInstanceState(outState);  
         //在activity执行onSaveInstanceState时执行mMapView.onSaveInstanceState (outState),保存地图当前的状态  
         mapView.onSaveInstanceState(outState);  
     }  
     /** 
      * 初始化地图 
      * 
      * @param savedInstanceState 
      */  
     private void initMap(Bundle savedInstanceState) throws AMapException {  
         mapView = (MapView) findViewById(R.id.map_view);  
         //在activity执行onCreate时执行mMapView.onCreate(savedInstanceState),创建地图  
         mapView.onCreate(savedInstanceState);  
         //初始化地图控制器对象  
         aMap = mapView.getMap();  
         //设置最小缩放等级为16 ,缩放级别范围为[3, 20]  
         aMap.setMinZoomLevel(12);  
         //开启室内地图  
         aMap.showIndoorMap(true);  
         aMap.setOnMapClickListener(this);  
         aMap.setOnMapLongClickListener(this);  
         // 自定义精度范围的圆形边框颜色  都为0则透明  
         myLocationStyle.strokeColor(Color.argb(0, 0, 0, 0));  
         // 自定义精度范围的圆形边框宽度  0 无宽度  
         myLocationStyle.strokeWidth(0);  
         // 设置圆形的填充颜色  都为0则透明  
         myLocationStyle.radiusFillColor(Color.argb(0, 0, 0, 0));  
         //设置定位蓝点的Style  
         aMap.setMyLocationStyle(myLocationStyle);  
         // 设置定位监听  
         aMap.setLocationSource(this);  
         // 设置为true表示显示定位层并可触发定位,false表示隐藏定位层并不可触发定位,默认是false  
         aMap.setMyLocationEnabled(true);  
         //实例化UiSettings类对象  
         mUiSettings = aMap.getUiSettings();  
         //隐藏缩放按钮  
         mUiSettings.setZoomControlsEnabled(false);  
         //显示比例尺 默认不显示  
         mUiSettings.setScaleControlsEnabled(true);  
         //构建GeocodeSearch对象  
         geocodeSearch = new GeocodeSearch(this);  
         geocodeSearch.setOnGeocodeSearchListener(this);  
     }  
   
     /** 
      * 通过经纬度获取地址 
      * 
      * @param latLng 
      */  
     private void latlonToAddress(LatLng latLng) {  
         //位置点  通过经纬度进行构建  
         LatLonPoint latLonPoint = new LatLonPoint(latLng.latitude, latLng.longitude);  
         //逆编码查询  第一个参数表示一个Latlng,第二参数表示范围多少米,第三个参数表示是火系坐标系还是GPS原生坐标系  
         RegeocodeQuery query = new RegeocodeQuery(latLonPoint, 20, GeocodeSearch.AMAP);  
         //异步获取地址信息  
         geocodeSearch.getFromLocationAsyn(query);  
     }  
     @Override  
     public void activate(OnLocationChangedListener onLocationChangedListener) {  
         mListener = onLocationChangedListener;  
         if (mLocationClient == null) {  
             mLocationClient.startLocation();//启动定位  
         }  
     }  
     @Override  
     public void deactivate() {  
         mListener = null;  
         if (mLocationClient != null) {  
             mLocationClient.stopLocation();  
             mLocationClient.onDestroy();  
         }  
         mLocationClient = null;  
     }  
     /** 
      * 浮动按钮点击查询附近POI 
      * 
      * @param view 
      */  
     public void queryPOI(View view) throws AMapException {  
         //构造query对象  
         query = new PoiSearch.Query("购物", "", cityCode);  
         // 设置每页最多返回多少条poiitem  
         query.setPageSize(10);  
         //设置查询页码  
         query.setPageNum(1);  
         //构造 PoiSearch 对象  
         poiSearch = new PoiSearch(this, query);  
         //设置搜索回调监听  
         poiSearch.setOnPoiSearchListener(this);  
         //发起搜索附近POI异步请求  
         poiSearch.searchPOIAsyn();  
     }  
     @Override  
     public void onPoiSearched(PoiResult poiResult, int i) {  
         //解析result获取POI信息  
         //获取POI组数列表  
         ArrayList<PoiItem> poiItems = poiResult.getPois();  
         for (PoiItem poiItem : poiItems) {  
             Log.d("MainActivity", " Title:" + poiItem.getTitle() + " Snippet:" + poiItem.getSnippet());  
         }  
     }  
     @Override  
     public void onPoiItemSearched(PoiItem poiItem, int i) {  
   
     }  
     @Override  
     public void onMapClick(LatLng latLng) {  
         showMsg("点击了地图,经度:" + latLng.longitude + ",纬度:" + latLng.latitude);  
         latlonToAddress(latLng);  
         updateMapCenter(latLng);  
     }  
     @Override  
     public void onMapLongClick(LatLng latLng) {  
         showMsg("长按了地图,经度:" + latLng.longitude + ",纬度:" + latLng.latitude);  
         latlonToAddress(latLng);  
     }  
     @Override  
     public void onRegeocodeSearched(RegeocodeResult regeocodeResult, int rCode) {  
         //解析result获取地址描述信息  
         if (rCode == PARSE_SUCCESS_CODE) {  
             RegeocodeAddress regeocodeAddress = regeocodeResult.getRegeocodeAddress();  
             //显示解析后的地址  
             showMsg("地址:" + regeocodeAddress.getFormatAddress());  
         } else {  
             showMsg("获取地址失败");  
         }  
     }  
   
     @Override  
     public void onGeocodeSearched(GeocodeResult geocodeResult, int i) {  
         if (i == PARSE_SUCCESS_CODE) {  
             List<GeocodeAddress> geocodeAddressList = geocodeResult.getGeocodeAddressList();  
             if (geocodeAddressList != null && geocodeAddressList.size() > 0) {  
                 LatLonPoint latLonPoint = geocodeAddressList.get(0).getLatLonPoint();  
                 //显示解析后的坐标  
                 showMsg("坐标csac:" + latLonPoint.getLongitude() + "," + latLonPoint.getLatitude());  
                 LatLng latLng = new LatLng(latLonPoint.getLatitude(), latLonPoint.getLongitude());  
                 updateMapCenter(latLng);  
             }  
         } else {  
             showMsg("获取坐标失败");  
         }  
     }  
     @Override  
     public boolean onKey(View v, int keyCode, KeyEvent event) {  
         if (keyCode == KeyEvent.KEYCODE_ENTER && event.getAction() == KeyEvent.ACTION_UP) {  
             //获取输入框的值  
             String address = etAddress.getText().toString().trim();  
             if (address == null || address.isEmpty()) {  
                 showMsg("请输入地址");  
             } else {  
                 InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);  
                 //隐藏软键盘  
                 imm.hideSoftInputFromWindow(getWindow().getDecorView().getWindowToken(), 0);  
                 // name表示地址,第二个参数表示查询城市,中文或者中文全拼,citycode、adcode  
                 GeocodeQuery query = new GeocodeQuery(address, city);  
                 geocodeSearch.getFromLocationNameAsyn(query);  
             }  
             return true;  
         }  
         return false;  
     }  
     /** 
      * 改变地图中心位置 
      * 
      * @param latLng 位置 
      */  
     private void updateMapCenter(LatLng latLng) {  
         // CameraPosition 第一个参数: 目标位置的屏幕中心点经纬度坐标。  
         // CameraPosition 第二个参数: 目标可视区域的缩放级别  
         // CameraPosition 第三个参数: 目标可视区域的倾斜度,以角度为单位。  
         // CameraPosition 第四个参数: 可视区域指向的方向,以角度为单位,从正北向顺时针方向计算,从0度到360度  
 Da 
         //位置变更  
         CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition);  
         //改变位置  
         aMap.animateCamera(cameraUpdate);  
     }  
 }  

更新帖子

  1. 该模块实现更新修改用户已经发布的帖子。

  2. 核心代码

     public class UpdataPost extends AppCompatActivity {  
         private ImageView imageView;  
         private EditText editText1;  
         private EditText editText2;  
         private EditText editText3;  
         private Toolbar toolbar;  
         private Button button;  
         private Connection connection;  
         @Override  
         protected void onCreate(Bundle savedInstanceState) {  
             super.onCreate(savedInstanceState);  
             setContentView(R.layout.activity_updata_post);  
             imageView = (ImageView) findViewById(R.id.imageUp);  
             editText1  = (EditText) findViewById(R.id.upAuthor);  
             editText2 = (EditText) findViewById(R.id.uptitle);  
             editText3 = (EditText) findViewById(R.id.upcontent);  
             Intent intent = getIntent();  
             String title = intent.getStringExtra("title");  
             final String content = intent.getStringExtra("content");  
             editText2.setText(title);  
             editText3.setText(content);  
             button = (Button) findViewById(R.id.buttonUp);  
             button.setOnClickListener(new View.OnClickListener() {  
                 @Override  
                 public void onClick(View v) {  
                     new Thread(new Runnable() {  
                         @Override  
                         public void run() {  
                             try{  
                                connection = MySQLConnections.getConnection("blog");  
                                 String title1 = editText2.getText().toString();  
                                 String content1 = editText3.getText().toString();  
                                 String sql = "update Blog set title='"+title1+"' where content='"+content+"'";  
                                 PreparedStatement pst;  
                                 pst = connection.prepareStatement(sql);  
                                 pst.executeUpdate();  
                                 sql = "update Blog set content='"+content1+"' where title='"+title1+"'";  
                                 pst.close();  
                                 connection.close();  
                             }catch (Exception e){  
                                 e.printStackTrace();  
                             }  
                         }  
                     }).start();  
                 }  
             });  
         }  
     }  
    

数据库设计

  1. News

    public class News {  
        private String title;  
        private String content;  
        private String author;  
        private int id;  
        private String image;  
        public String getTitle() {  
            return title;  
        }  
        public void setTitle(String title) {  
            this.title = title;  
        }  
        public String getContent() {  
            return content;  
        }  
        public void setContent(String content) {  
            this.content = content;  
        }  
        public int getId() {  
            return id;  
        }  
        public void setId(int id) {  
            this.id = id;  
        }  
        public String getAuthor() {  
            return author;  
        }  
        public void setAuthor(String author) {  
            this.author = author;  
        }  
        public String getImage() {  
            return image;  
        }  
        public void setImage(String image) {  
            this.image = image;  
        }  
    }  
    
  2. MyPost

     public class MyPost extends DataSupport {  
         private String username;  
         private String newstitle;  
         private String newscontent;  
         private String imagePost;  
         public String getNewstitle() {  
             return newstitle;  
         }  
         public void setNewstitle(String newstitle) {  
             this.newstitle = newstitle;  
         }  
         public String getUsername() {  
             return username;  
         }  
         public void setUsername(String username) {  
             this.username = username;  
         }  
         public String getNewscontent() {  
             return newscontent;  
         }  
         public void setNewscontent(String newscontent) {  
             this.newscontent = newscontent;  
         }  
         public String getImagePost() {  
             return imagePost;  
         }  
         public void setImagePost(String imagePost) {  
             this.imagePost = imagePost;  
         }  
      }  
    
  3. User

    public class User extends DataSupport {  
        private String name;  
        private String password;  
        private String image;  
        public String getName() {  
            return name;  
        }  
        public void setName(String name) {  
            this.name = name;  
        }  
        public String getPassword() {  
            return password;  
        }  
        public void setPassword(String password) {  
            this.password = password;  
        }  
        public String getImage() {  
            return image;  
        }  
        public void setImage(String image) {  
            this.image = image;  
        }  
    }  
    

工具包类

  1. ImageHelper

    • 实现Bitmap和String的转换
    public class ImageHelper {  
      public static Bitmap stringToBitmap(String string) {  
          // 将字符串转换成Bitmap类型  
          Bitmap bitmap = null;  
          try {  
              byte[] bitmapArray;  
              bitmapArray = Base64.decode(string, Base64.DEFAULT);  
              bitmap = BitmapFactory.decodeByteArray(bitmapArray, 0,  
                      bitmapArray.length);  
          } catch (Exception e) {  
              e.printStackTrace();  
          }  
          return bitmap;  
      }  
      //把bitmap转换成字符串  
      public static String bitmapToString(Bitmap bitmap) {  
          String string = null;  
          ByteArrayOutputStream btString = new ByteArrayOutputStream();  
          bitmap.compress(Bitmap.CompressFormat.JPEG, 100, btString);  
          byte[] bytes = btString.toByteArray();  
          string = Base64.encodeToString(bytes, Base64.DEFAULT);  
          return string;  
      }  
    }  
    
  2. MySQLConnection

    • 实现服务器数据库的连接以及数据库的操作(导入MySqlConnector包)。
    public class MySQLConnections {  
      public static int number = 0;  
      private String driver = "";  
      private String dbURL = "";  
      private String user = "";  
      private String password = "";  
      private static MySQLConnections connection = null;  
      private static Connection conn = null;  
      private static PreparedStatement stmt = null;  
      private static List<News>newsList = new ArrayList<News>();  
      private MySQLConnections() throws Exception {  
          driver = "com.mysql.jdbc.Driver";  
          dbURL = "jdbc:mysql://182.92.153.231:3306/blog";  
          user = "lkk";  
          password = "123456";  
          System.out.println("dbURL:" + dbURL);  
      }  
      public static Connection getConnection(String dbName) {  
          Connection conn = null;  
          if (connection == null) {  
              try {  
                  connection = new MySQLConnections();  
              } catch (Exception e) {  
                  e.printStackTrace();  
                  return null;  
              }  
          }  
          try {  
              Class.forName(connection.driver);  
              conn = DriverManager.getConnection(connection.dbURL,  
                      connection.user, connection.password);  
          } catch (Exception e) {  
              e.printStackTrace();  
          }  
          return conn;  
      }  
      public static int insertIntoData(final int id, final String author,final String title,final String content,String image) throws SQLException {//增加数据  
          Connection  conn = null;  
          conn = getConnection("blog");//填写需要连接的数据库的名称,我是用的是person  
          //使用DriverManager获取数据库连接  
          Statement stmt = conn.createStatement();  
          //使用Connection来创建一个Statment对象  
          String sql = "insert INTO Blog (id,author,title,content,image)VALUES('"+id+"','"+author+"','"+title+"','"+content+"','"+image+"')";  
          return stmt.executeUpdate(sql);//返回的同时执行sql语句,返回受影响的条目数量,一般不作处理  
      }  
      public static List<News> querycol() throws SQLException {//读取某一行  
          //加载数据库驱动  
          final Handler handler = new Handler(new Handler.Callback() {  
              @Override  
              public boolean handleMessage(Message message) {  
                  //下一步执行的代码  
                  return false;  
              }  
          });  
          new Thread(new Runnable() {  
              @Override  
              public void run() {  
                  Message msg = new Message();//message用于给handler传递参数  
                  try {  
                      //调用连接数据库方法的代码  
                      conn = MySQLConnections.getConnection("Blog");  
                  } catch (Exception e) {  
                      e.printStackTrace();  
                      Log.d("TAG", " 数据操作异常");  
                  }handler.sendMessage(msg);  
                  try {  
                      String sql = "select * from Blog";  
                      if(conn != null){  
                          stmt = conn.prepareStatement(sql);  
                          conn.setAutoCommit(false);  
                          ResultSet rs =stmt.executeQuery();//用rs接收sql语句返回的查询结果  
                          //执行查询语句并且保存结果  
                          while (rs.next()){  
                              News news = new News();  
                              news.setId(Integer.parseInt(rs.getString("id")));  
                              news.setAuthor(rs.getString("author"));  
                              news.setTitle(rs.getString("title"));  
                              news.setContent(rs.getString("content"));  
                              news.setImage(rs.getString("image"));  
                              newsList.add(news);  
                          }  
                          rs.close();  
                      }  
                      sleep(2000);  
                  } catch (InterruptedException e) {  
                      e.printStackTrace();  
                  } catch (SQLException e) {  
                      e.printStackTrace();  
                  }  
              }  
          }).start();  
          return newsList;  
      }  
      public static int insertIntoUser(String name, String password, String image) throws SQLException {  
          Connection  conn = null;  
          conn = getConnection("blog");//填写需要连接的数据库的名称,我是用的是person  
          //使用DriverManager获取数据库连接  
          Statement stmt = conn.createStatement();  
          //使用Connection来创建一个Statment对象  
          String sql = "insert INTO User (name,password,image)VALUES('"+name+"','"+password+"','"+image+"')";  
          return stmt.executeUpdate(sql);  
      }  
    }  
    

项目Gitee

  • 地址:https://gitee.com/lkksxxdxxd/android
  • 2
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

高明爱圣子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值