使用HorizontalScrollView简单实现柱状图

有个爱折腾的美工是个什么体验。。。那就是效果,也是,android也就是个UI,UI注重的是用户体验,良好的用户体验跟舒适的UI效果是分不开的。这次要做的效果就是,做完测试后提交的历史记录,以柱状图的形式呈现,那么把这个父布局设置成HorizontalScrollView,把树状图的滚动效果交给HorizontalScrollView,那么问题来了,HorizontalScrollView只能有一个子布局,那么就在这里面嵌套一层最好用的LinearLayout,把它的子布局方向设置成horizontal水平,然后把一个个子View创建出来,add进来就可以了。其中的难点就是嵌套了3层,如何获取子view,并监听它们了。。。不难,看完真的就好简单了。。。

最终效果图

初步的效果图

historyresult_item.xml

1、按照我们的思路,我们写好xml文件

act_historytest.xml

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

    <HorizontalScrollView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:scrollbars="none" >

        <LinearLayout
            android:id="@+id/id_history"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="top"
            android:orientation="horizontal" >
        </LinearLayout>
    </HorizontalScrollView>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/grey" >

        <TextView
            android:id="@+id/situation_content"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="分数对应您的健康状况"
            android:textColor="@android:color/black"
            android:textSize="14sp" />
    </LinearLayout>

</LinearLayout>


historyresult_item.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="290dp"
    android:background="@android:color/white"
    android:padding="10dp" >

    <TextView
        android:id="@+id/his_date"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:text="2014.1.5"
        android:textSize="12sp" />

    <ImageView
        android:id="@+id/his_length"
        android:layout_width="30dp"
        android:layout_height="170dp"
        android:layout_above="@id/his_date"
        android:layout_centerHorizontal="true"
        android:layout_margin="5dp"
        android:background="@color/grey" />

    <TextView
        android:id="@+id/his_count"
        android:layout_above="@id/his_length"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:background="@drawable/noselect_result"
        android:gravity="center"
        android:text="32"
        android:textColor="@android:color/white"
        android:textSize="14sp" />

</RelativeLayout>

2、那么问题来了,到我们的java文件看看

ChartFragment.java文件代码如下

package com.example.chartdemo;

import java.util.ArrayList;
import java.util.List;

import com.example.chartdemo.R.color;
import com.example.chartdemo.R.drawable;

import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.util.SparseArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

public class ChartFragment extends Fragment implements OnClickListener {
    private View view;
    private LinearLayout mGallery;
    private LayoutInflater mInflater;
    private TextView main_content;
    private List<Integer> count; // 分数
    private List<String> times; // 日期
    private SparseArray<String> mySparse;

    @Override
    public View onCreateView(LayoutInflater inflater,
            @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        // 动态加载布局
        view = inflater.inflate(R.layout.act_historytest, container, false);
        return view;
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        initView();
        initData();
        setOnListener();
    }

    private void setOnListener() {
        if (mInflater == null)
            mInflater = LayoutInflater.from(getActivity());
        for (int i = 0; i < count.size(); i++) {
            View view = mInflater.inflate(R.layout.historyresult_item,
                    mGallery, false);
            ImageView img = (ImageView) view.findViewById(R.id.his_length);
            // 获取图片的大小,自定义设置图片的高度
            LayoutParams params = img.getLayoutParams();
            params.height = count.get(i) * 4;
            img.setLayoutParams(params);
            TextView txt = (TextView) view.findViewById(R.id.his_date);
            TextView txtdate = (TextView) view.findViewById(R.id.his_count);
            txt.setText(times.get(i).toString());
            txtdate.setText(String.valueOf(count.get(i)));
            view.setId(i);// 设定view的id,把i设置成当前View的id
            view.setOnClickListener(this);//每一个子项目注册监听事件
            if (i == 0) {
                // 默认选中第一个
            img.setBackgroundResource(color.btn_login);
    txtdate.setBackgroundResource(drawable.select_result);
                txtdate.setTextColor(color.black);
            }
            mGallery.addView(view);
        }

    }

    private void initData() {
        // 测试数据
        mySparse = new SparseArray<String>();
        count = new ArrayList<Integer>();
        times = new ArrayList<String>();
        for (int i = 10; i <= 90; i += 10) {
            mySparse.put(i, "2016-5-0" + i / 10);
            count.add(i);
            times.add("2016-5-0" + i / 10);
        }
    }

    private void initView() {
        mGallery = (LinearLayout) view.findViewById(R.id.id_history);
        main_content = (TextView) view.findViewById(R.id.situation_content);
    }
    /*注意这里的mGallery是我们把自定义好的view后一个个add进来的
     *view容器,mGallery.getChildAt(v.getId()),刚好是以位置
     *进行排序add进来的,这里获取的id也就是上面的i
     */
    @Override
    public void onClick(View v) {
    // 至于这里为什么要用for循环的话。。。额,那就是是要做刷新,刷新整个视图
        for (int i = 0; i < mGallery.getChildCount(); i++) {
            if (v.getId() == i) {
                // 获取点击的子视图
                TextView txtdate = (TextView) mGallery.getChildAt(v.getId())
                        .findViewById(R.id.his_date);
                TextView txtcount = (TextView) mGallery.getChildAt(v.getId())
                        .findViewById(R.id.his_count);
                ImageView img = (ImageView) mGallery.getChildAt(v.getId())
                        .findViewById(R.id.his_length);
                img.setBackgroundResource(color.btn_login);
                txtcount.setBackgroundResource(drawable.select_result);
                txtdate.setTextColor(color.black);
                int count = Integer.parseInt(txtcount.getText().toString());
                if (count >= 80) {
                    main_content.setText(count + "分,非常健康");
                } else if (count >= 60) {
                    main_content.setText(count + "分,正常");
                } else {
                    main_content.setText(count + "分,不正常");
                }
            } else {
                // 获取未点击的视图
                TextView txtdate = (TextView) mGallery.getChildAt(i)
                        .findViewById(R.id.his_date);
                TextView txtcount = (TextView) mGallery.getChildAt(i)
                        .findViewById(R.id.his_count);
                ImageView img = (ImageView) mGallery.getChildAt(i)
                        .findViewById(R.id.his_length);
                img.setBackgroundResource(color.grey);
        txtcount.setBackgroundResource(drawable.noselect_result);
                txtdate.setTextColor(color.white);
            }
        }
    }
}

3、然后就实现好了,然后同时,美工又默默地加了分页效果,我特么。。。还是忍了。那么我们就用fragment吧,常说的碎片,最后在外面包裹一层Activity。。。

最终效果图

MainActivity.java中的代码

package com.example.chartdemo;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.view.Window;
import android.widget.ImageView;
import android.widget.RadioGroup;
import android.widget.RadioGroup.OnCheckedChangeListener;

public class MainActivity extends FragmentActivity {
    private RadioGroup radTab;
    // 将fragment初始化为数组便于管理
    Fragment[] fragmentGroup = { new ChartFragment(), new ListFragment() };
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.act_testrecord);
        initView();
        initData();
        setonListener();
    }
    private void setonListener() {
        // 点击switch更换界面
        radTab.setOnCheckedChangeListener(new OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(RadioGroup group, int checkedId) {
                switch (checkedId) {
                case R.id.rb_left:
                    setFragment(0);
                    break;
                case R.id.rb_right:
                    setFragment(1);
                    break;
                }
            }
        });
    }
    private void initData() {
        setFragment(0);// 默认在左边
    }
    private void initView() {
        radTab = (RadioGroup) findViewById(R.id.rgb_switch);
    }
    // 显示选中的fragment
    private void setFragment(int showId) {
        getSupportFragmentManager().beginTransaction()
                .replace(R.id.record_content, fragmentGroup[showId]).commit();
    }

}

4、看下另一边的listview,主要考量的就是圆角效果(corners),虚线效果(line),描边效果(stroke),实心效果(solid),也就是人们常说的用shape.xml文件对视图进行美化

这里写图片描述

最主要的就是那个虚线效果了。。。不百度,真不清楚,还要关闭硬件加速才能显示。。。

shape_line.xml

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

    <stroke
        android:dashGap="3dp"
        android:dashWidth="3dp"
        android:width="1dp"
        android:color="@color/gray" />


    <size android:height="2dp" />

</shape>

上代码:

ListFragment.java

package com.example.chartdemo;

import java.util.ArrayList;
import java.util.List;

import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListView;
import android.widget.SimpleAdapter;

public class ListFragment extends Fragment {
    private View view;
    private ListView testListView;

    @Override
    @Nullable
    public View onCreateView(LayoutInflater inflater,
            @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        view = inflater.inflate(R.layout.act_historyverication, container,
                false);
        // 关闭activity的硬件加速功能,为了显示虚线
        view.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
        return view;
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        initView();
        initData();
        setListener();
    }

    private void setListener() {

    }

    private void initData() {
        List<String> testL = new ArrayList<String>();
        for (int i = 0; i < 10; i++) {
            testL.add(i + "");
        }
        testListView.setAdapter(new testAdapter(getActivity(),
                R.layout.historyverication_item, testL));
    }

    private void initView() {
        testListView = (ListView) view.findViewById(R.id.lvverication);
    }

}

然后我觉得这个功能比较容易拓展的功能有产品列表,附图。利用了HorizontalScrollView可以很容易实现

这里写图片描述

最后,总结下,其实我有偷懒的地方,就是标头那个切换其实是使用了xml文件中的selector进行图片的切换,其实我第一反应是用tabHost的。。。但是无奈碎片横行啊,fragment的使用。然后就是我年轻不懂事,没用android自带的图表类库,其实实现的方式挺简单的,也很符合正常的逻辑。。。纯手工,我给自己点赞

最后附上demo下载源码:http://download.csdn.net/detail/z_zt_t/9560642

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值