Khurram Majeed
Khurram Majeed

Reputation: 2411

Creating android custom list in activity or fragment layout

I am trying to create a GUI for my application like enter image description here For my Status Tab I tried to use table-layout inside relative-layout but it was no way like this mockup. But very bad

The data comes from database, the GUI is static i.e. values get changed based on the data read from database but the layout should stay the same.

I think I have to use some kind custom list-view. inside these fragments. Plus I have a refresh actionitem in the first tab.

I will highly appreciate If someone can advise me if this is possible and guide me in the right direction.

FYI, This app is only for ICS and up so I an not going to use libraries like ActionBarSherlock etc.

Upvotes: 0

Views: 4471

Answers (1)

Roger Rapid
Roger Rapid

Reputation: 956

At first, this question seemed a bit abstract to me, not a specific problem. But then it became a challenge to recreate. ;) Here's how you could start:

First, create a custom attribute for our custom table view:

res/values/attrs.xml

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

<attr name="label" format="string" />

<declare-styleable name="AverageTableView">
    <attr name="label" />
</declare-styleable>

</resources>

Define the styles we're going to use:

res/values/styles.xml

<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<style name="Table">
    <item name="android:layout_width">fill_parent</item>
    <item name="android:layout_height">fill_parent</item>
    <item name="android:shrinkColumns">*</item>
    <item name="android:stretchColumns">*</item>
</style>

<style name="Cell">
    <item name="android:gravity">center</item>
    <item name="android:textSize">10sp</item>
</style>

<style name="Cell.Header">
    <item name="android:textStyle">bold</item>
</style>

<style name="Divider">
    <item name="android:layout_width">fill_parent</item>
    <item name="android:layout_height">1dip</item>
    <item name="android:layout_margin">6dip</item>
    <item name="android:background">?android:attr/listDivider</item>
</style>

</resources>

create the layout for out custom table view:

res/layout/average_table.xml

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

<TableRow android:layout_width="fill_parent"
    android:layout_height="wrap_content">

    <TextView android:id="@+id/table_header"
        android:layout_span="3"
        android:layout_marginLeft="6dip"
        android:padding="3dip"
        android:textColor="@android:color/holo_blue_light"
        android:textSize="10sp" />

</TableRow>

<View
    android:layout_height="2dip"
    android:background="@android:color/holo_blue_light" />

<TableRow android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:paddingTop="6dip">

    <TextView style="@style/Cell.Header"
        android:text="Today" />
    <TextView style="@style/Cell.Header"
        android:text="This Month" />
    <TextView style="@style/Cell.Header"
        android:text="All Time" />

</TableRow>

<TableRow android:layout_width="fill_parent"
    android:layout_height="wrap_content">

    <View style="@style/Divider" />
    <View style="@style/Divider" />
    <View style="@style/Divider" />

</TableRow>

<TableRow android:layout_width="fill_parent"
    android:layout_height="wrap_content">

    <TextView android:id="@+id/day_value"
        style="@style/Cell" />
    <TextView android:id="@+id/month_value"
        style="@style/Cell" />
    <TextView android:id="@+id/all_value"
        style="@style/Cell" />

</TableRow>

<TableRow android:layout_width="fill_parent"
    android:layout_height="wrap_content">

    <View style="@style/Divider" />
    <View style="@style/Divider" />
    <View style="@style/Divider" />

</TableRow>

</merge>

Create the custom table view:

src/com/test/app/AverageTableView.java

package com.test.app;

import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.view.View;
import android.widget.TextView;
import android.widget.TableLayout;

public class AverageTableView extends TableLayout {
private TextView mHeader;

private TextView mDay;
private TextView mMonth;
private TextView mAll;

public AverageTableView( Context pContext ) {
    this( pContext, null );
}

public AverageTableView( Context pContext, AttributeSet pAttrs ) {
    super( pContext, pAttrs );
    initView( pContext, pAttrs );
}

private void initView( Context pContext, AttributeSet pAttrs ) {
    View.inflate( pContext, R.layout.average_table, this );
    mHeader = ( TextView ) findViewById( R.id.table_header );

    mDay = ( TextView ) findViewById( R.id.day_value );
    mMonth = ( TextView ) findViewById( R.id.month_value );
    mAll = ( TextView ) findViewById( R.id.all_value );

    TypedArray a = pContext.getTheme().obtainStyledAttributes(
        pAttrs, R.styleable.AverageTableView, 0, 0 );
    try {
        String label = a.getString( R.styleable.AverageTableView_label );
        setHeaderLabel( label == null ? "Header" : label );
    } finally {
        a.recycle();
    }
}

public String getHeaderLabel() {
    return mHeader.getText().toString();
}

public void setHeaderLabel( String pLabel ) {
    mHeader.setText( pLabel );
}

public String getDayValue() {
    return mDay.getText().toString();
}

public void setDayValue( String pValue ) {
    mDay.setText( pValue );
}

public String getMonthValue() {
    return mMonth.getText().toString();
}

public void setMonthValue( String pValue ) {
    mMonth.setText( pValue );
}

public String getAllValue() {
    return mAll.getText().toString();
}

public void setAllValue( String pValue ) {
    mAll.setText( pValue );
}
}

We then use our custom table view in our fragment layout:

res/layout/detail.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:custom="http://schemas.android.com/apk/res/com.test.app"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:padding="12dip" >

<com.test.app.AverageTableView android:id="@+id/cpu_table"
    style="@style/Table"
    custom:label="CPU Usage Average" />
<com.test.app.AverageTableView android:id="@+id/ram_table"
    style="@style/Table"
    custom:label="RAM Usage Average" />

</LinearLayout>

And finally, fill the table in our fragment:

src/com/test/app/DetailFragment.java

package com.test.app;

import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class DetailFragment extends Fragment {
AverageTableView mCPU;
AverageTableView mRAM;

@Override
protected void onCreate( Bundle savedInstanceState ) {
    super.onCreate( savedInstanceState );
}

@Override
public View onCreateView( LayoutInflater pInflater, ViewGroup pContainer, Bundle pSavedInstanceState ) {
    View view = pInflater.inflate( R.layout.detail, pContainer, false );

    mCPU = ( AverageTableView ) view.findViewById( R.id.cpu_table );
    mRAM = ( AverageTableView ) view.findViewById( R.id.ram_table );

    mCPU.setDayValue( "77%" );
    mCPU.setMonthValue( "77%" );
    mCPU.setAllValue( "64%" );

    mRAM.setDayValue( "88%" );
    mRAM.setMonthValue( "56%" );
    mRAM.setAllValue( "64%" );

    return view;
}
}

Hope this helps!

Upvotes: 3

Related Questions