I need to create a layout, which must be divided in half, like this:
-------
| |
| A |
| |
-------
| |
| B |
| |
-------
Where:
A - this is the place, where I can draw points with a finger;
B - it is an example ListView.
It looks like no object from class SampleView was created, so painting in A doesn't work.
What's wrong with that?
How do I need to fix painting?
drawing_activity.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1"
android:orientation="vertical" >
<View
class="com.example.proj.SampleView"
android:id="#+id/sampleView1"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight=".50" />
<ListView
android:id="#+id/listView1"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight=".50" >
</ListView>
</LinearLayout>
SampleView.java:
package com.example.proj;
import java.util.ArrayList;
import java.util.List;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
public class SampleView extends View implements OnTouchListener {
private static final String TAG = "SampleView";
List<Point> points = new ArrayList<Point>();
Paint paint = new Paint();
public SampleView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
setFocusable(true);
setFocusableInTouchMode(true);
this.setOnTouchListener(this);
paint.setColor(Color.BLACK);
paint.setAntiAlias(true);
Log.i(TAG, "Created SampleView!");
}
#Override
public void onDraw(Canvas canvas) {
for (Point point : points) {
canvas.drawCircle(point.x, point.y, 5, paint);
Log.d(TAG, "Painting: "+point);
}
}
public boolean onTouch(View view, MotionEvent event) {
if(event.getAction() != MotionEvent.ACTION_DOWN)
return super.onTouchEvent(event);
Point point = new Point();
point.x = event.getX();
point.y = event.getY();
points.add(point);
invalidate();
Log.d(TAG, "point: " + point);
return true;
}
}
class Point {
float x, y;
#Override
public String toString() {
return x + ", " + y;
}
}
MainActivity.java:
package com.example.proj;
import java.util.ArrayList;
import android.os.Bundle;
import android.app.Activity;
import android.widget.ListView;
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.drawing_activity);
final ListView listview = (ListView) findViewById(R.id.listView1);
String[] values = new String[] { "Element1", "Element2" };
final ArrayList<String> list = new ArrayList<String>();
for (int i = 0; i < values.length; ++i) {
list.add(values[i]);
}
final StableArrayAdapter adapter = new StableArrayAdapter(this,
android.R.layout.simple_list_item_1, list);
listview.setAdapter(adapter);
}
}
In your xml must be:
<com.example.proj.SampleView
android:id="#+id/sampleView1"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight=".50" />
OR: view with non-capitalized "V"
<view
class="com.example.proj.SampleView"
android:id="#+id/sampleView1"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight=".50" />
Both tags view and View exist, however View will generate a new View class whereas view will generate from the class tag.
Related
Wasn't really sure how to ask this but...
My code is meant to generate ListView input on a button click.
When I click the button it should .execute() an Async which takes a list of items and adds them to an ArrayList< HashMap < String, String > > with a custom adapter.
The problem is, when I press the button, it generates the list and adds it to the ListView, however, instead of going... 1, 2, 3, 4, 5, ....20 it goes in a random order. 1, 2, 5, 1, 3, 0, 6, 7, 8, 3, 1 ...
And if I scroll up or down the ListView it changes.
activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
tools:context=".MainActivity">
<Button
android:id="#+id/bLoadData"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:text="Load api data" />
<ListView
android:id="#+id/lvMovies"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_above="#id/bLoadData"
android:background="#efefef" />
</RelativeLayout>
results_layout.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="wrap_content"
android:orientation="vertical">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageView android:id="#+id/ivPosters"
android:layout_width="120dp"
android:layout_height="120dp"
android:src="#drawable/place_holder_img"/>
<TextView
android:id="#+id/results_layout_tv_movie_name"
android:layout_width="0dp"
android:layout_height="fill_parent"
android:layout_weight="1"
android:paddingBottom="10dp"
android:paddingLeft="20dp"
android:paddingStart="20dp"
android:paddingTop="10dp"
android:text="hellow"
android:textColor="#000"
android:textSize="20sp" />
</LinearLayout>
</LinearLayout>
MainActivity.class:
package com.example.zdroa.testinggrounds;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.ListView;
import java.util.ArrayList;
import java.util.HashMap;
public class MainActivity extends AppCompatActivity {
static ArrayList<HashMap<String, String>> posters;
ListView listView;
Button button;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = (ListView) findViewById(R.id.lvMovies);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
System.out.println(posters.get(position).values().toString());
}
});
button = (Button) findViewById(R.id.bLoadData);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
posters = new ArrayList<>();
ImageLoadTask ilt = new ImageLoadTask();
ilt.execute();
}
});
}
private class ImageLoadTask extends AsyncTask<Void, Void, ArrayList<HashMap<String, String>>> {
#Override
protected ArrayList<HashMap<String, String>> doInBackground(Void... params) {
posters = getPathFromAPI();
return posters;
}
#Override
protected void onPostExecute(ArrayList<HashMap<String, String>> result) {
SearchAdapter adapter = new SearchAdapter(MainActivity.this, result);
listView.setAdapter(adapter);
}
private ArrayList<HashMap<String, String>> getPathFromAPI() {
String moviePaths[] = new String[10];
for (int i = 0; i < moviePaths.length; i++) {
HashMap<String, String> map = new HashMap<>();
String s = "path";
map.put(s, s + "_" + i);
moviePaths[i] = "path_" + i;
posters.add(map);
}
return posters;
}
}
}
SearchAdapter.class:
package com.example.zdroa.testinggrounds;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.support.v4.content.ContextCompat;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import com.squareup.picasso.Picasso;
import java.util.ArrayList;
import java.util.HashMap;
public class SearchAdapter extends BaseAdapter {
private Context mContext;
private ArrayList<HashMap<String, String>> array;
private ImageView imageView;
private TextView textView;
SearchAdapter(Context context, ArrayList<HashMap<String, String>> paths) {
mContext = context;
array = paths;
}
#Override
public int getCount() {
return array.size();
}
#Override
public Object getItem(int position) {
return null;
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = View.inflate(mContext, R.layout.results_layout, null);
imageView = (ImageView) convertView.findViewById(R.id.ivPosters);
textView = (TextView) convertView.findViewById(R.id.results_layout_tv_movie_name);
}
Drawable drawable = ContextCompat.getDrawable(mContext, R.drawable.place_holder_img);
String link_end = array.get(position).values().toString();
Picasso.with(mContext)
.load("http://image.tmdb.org/t/p/w185" + link_end)
// .resize(width, (int) (width * 1.5))
.placeholder(drawable)
.into(imageView);
textView.setText(position+"");
return convertView;
}
}
Your imageview and textview references are only set when the convertview is null...move those lines out of the parenthesis.
in onPost in Asyntask class
after creating and setting the adapter for listview
make the list that you're using in list view
list=new ArrayList<>();
**I have this code to show the installed applications in Android. I also want to display the selected applications by the user in Grid view. How can I do that in this code?
And is there always a need for adapter for grid-view also?**
This is my first activity:
package com.abhi.test;
import java.util.ArrayList;
import com.example.applist.R;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class Startup extends Activity {
Button bIns, bSel;
ArrayList<String> myList = new ArrayList<String>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
bIns = (Button) findViewById(R.id.bList);
bSel = (Button) findViewById(R.id.bGrid);
}
public void viewList(View view) {
Intent intent = new Intent(getApplicationContext(), MainActivity.class);
startActivity(intent);
}
public void viewGrid(View view) {
myList = (ArrayList<String>) getIntent().getSerializableExtra("mySelectedList");
Intent intent = new Intent(getApplicationContext(), Last.class);
intent.putExtra("mySelectedList",myList);
startActivity(intent);
}
}
This is my second activity:
package com.abhi.test;
import java.util.ArrayList;
import com.abhi.test.ApplicationAdapter;
import java.util.List;
import com.example.applist.R;
import android.app.ListActivity;
import android.app.ProgressDialog;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends ListActivity {
private PackageManager packageManager = null;
private List<ApplicationInfo> applist = null;
private ApplicationAdapter listadaptor = null;
Button button;
Bundle bundle;
CheckBox checkbox;
ArrayList<ApplicationInfo> selectedapplication = null;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
packageManager = getPackageManager();
button = (Button) findViewById(R.id.button);
checkbox = (CheckBox) findViewById(R.id.cb_app);
new LoadApplications().execute();
//Intent intent = new Intent(this,Last.class);
}
public void selectedApps(View view) {
//new ApplicationAdapter().selApps();
selectedapplication = ApplicationAdapter.finalList;
Intent intent = new Intent(MainActivity.this, Startup.class);
intent.putExtra("mySelectedList",selectedapplication);
startActivity(intent);
}
#Override
protected void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
ApplicationInfo app = applist.get(position);
try {
Intent intent = packageManager
.getLaunchIntentForPackage(app.packageName);
if (null != intent) {
startActivity(intent);
}
} catch (ActivityNotFoundException e) {
Toast.makeText(MainActivity.this, e.getMessage(), Toast.LENGTH_LONG)
.show();
} catch (Exception e) {
Toast.makeText(MainActivity.this, e.getMessage(), Toast.LENGTH_LONG)
.show();
}
}
private List<ApplicationInfo> checkForLaunchIntent(
List<ApplicationInfo> list) {
ArrayList<ApplicationInfo> applist = new ArrayList<ApplicationInfo>();
for (ApplicationInfo info : list) {
try {
if (packageManager.getLaunchIntentForPackage(info.packageName) != null)
{
applist.add(info);
}
} catch (Exception e) {
e.printStackTrace();
}
}
return applist;
}
private class LoadApplications extends AsyncTask<Void, Void, Void> {
private ProgressDialog progress = null;
#Override
protected Void doInBackground(Void... params) {
applist = checkForLaunchIntent(packageManager
.getInstalledApplications(PackageManager.GET_META_DATA));
listadaptor = new ApplicationAdapter(MainActivity.this,
R.layout.row, applist);
return null;
}
#Override
protected void onPostExecute(Void result) {
setListAdapter(listadaptor);
progress.dismiss();
super.onPostExecute(result);
}
#Override
protected void onPreExecute() {
progress = ProgressDialog.show(MainActivity.this, null,
"Loading application info...");
super.onPreExecute();
}
}
}
Array adapter for second activity:
package com.abhi.test;
import java.util.ArrayList;
import java.util.List;
import com.example.applist.R;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
public class ApplicationAdapter extends ArrayAdapter<ApplicationInfo> {
private List<ApplicationInfo> appsList = null;
private Context context;
int position1;
CheckBox checkBox;
private PackageManager packageManager;
public ArrayList<Boolean> checkList = new ArrayList<Boolean>();
private OnCheckedChangeListener listener;
public static ArrayList<ApplicationInfo> finalList = null;
public ApplicationAdapter(Context context, int textViewResourceId,
List<ApplicationInfo> appsList) {
super(context, textViewResourceId, appsList);
this.context = context;
this.appsList = appsList;
packageManager = context.getPackageManager();
for (int i = 0; i < appsList.size(); i++)
{
checkList.add(false);
}
}
#Override
public int getCount() {
if (appsList != null) {
return appsList.size();
} else {
return 0;
}
}
#Override
public ApplicationInfo getItem(int position) {
if (appsList != null) {
return appsList.get(position);
} else {
return null;
}
}
#Override
public long getItemId(int position) {
return position;
}
#Override //ibuilt function getView()--responsinle for making views
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
if ( view == null) {
LayoutInflater layoutInflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE); //Understand
view = layoutInflater.inflate(R.layout.row, null);
}
ApplicationInfo data = appsList.get(position);
if (data != null) {
TextView appName = (TextView) view.findViewById(R.id.app_name);
TextView packageName = (TextView) view.findViewById(R.id.app_paackage);
ImageView iconview = (ImageView) view.findViewById(R.id.app_icon);
position1=position;
checkBox = (CheckBox) view.findViewById(R.id.cb_app); //understand
checkBox.setTag(Integer.valueOf(position)); // set the tag so we can identify the correct row in the listener
checkBox.setChecked(checkList.get(position)); // set the status as we stored it
checkBox.setOnCheckedChangeListener(mListener); // set the listener
appName.setText(data.loadLabel(packageManager));
packageName.setText(data.packageName);
iconview.setImageDrawable(data.loadIcon(packageManager));
/* if(checkBox.isChecked())
{
finalList.add(data);
Toast.makeText(getContext(), "App Added", Toast.LENGTH_LONG).show();
}*/
}
return view;
}
OnCheckedChangeListener mListener = new OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
checkList.set((Integer)buttonView.getTag(),isChecked); // get the tag so we know the row and store the status
}
};
}
This is the last activity in which I want to show the selected applications by the user:
package com.abhi.test;
import java.util.ArrayList;
import com.example.applist.R;
import android.app.Activity;
import android.content.pm.ApplicationInfo;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.GridView;
public class Last extends Activity{
GridView gridview;
ArrayList<ApplicationInfo> appList;
String[] appName = new String[100];
String[] appPack = new String[100];
String[] appComp = new String[100];
ArrayList<String> appInfo = new ArrayList<String>();
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.last);
gridview = (GridView) findViewById(R.id.gridview);
appList = (ArrayList<ApplicationInfo>) getIntent().getSerializableExtra("mylist");
for(int i=0;i<appList.size();i++)
{
appName[i] = appList.get(i).name;
appPack[i] = appList.get(i).packageName;
appComp[i] = appName[i]+appPack[i];
appInfo.add(appComp[i]);
}
/* ArrayAdapter<ApplicationInfo> adapter = new ArrayAdapter<ApplicationInfo>(this,
android.R.layout.simple_list_item_1, appInfo);
gridview.setAdapter(adapter);*/
}
}
XML for the first activity:
<?xml version="1.0" encoding="UTF-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/rootLayout"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:background="#android:color/white"
android:orientation="vertical" >
<Button
android:id="#+id/bList"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:gravity="fill_horizontal"
android:onClick="viewList"
android:text="#string/bInstalledApps" />
<Button
android:id="#+id/bGrid"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:gravity="fill_horizontal"
android:onClick="viewGrid"
android:text="#string/bSelectedApps" />
</LinearLayout>
XML for the second activity:
<?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" >
<Button
android:id="#+id/button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:onClick="selectedApps"
android:text="Done"/>
<ListView
android:id="#android:id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="#id/button" />
</RelativeLayout>
row.xml for adapter:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/appdata"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<CheckBox
android:id="#+id/cb_app"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:gravity="center_vertical"
android:scaleX="1.50"
android:scaleY="1.50" />
<ImageView
android:id="#+id/app_icon"
android:layout_width="50dp"
android:layout_height="50dp"
android:padding="3dp"
android:scaleType="centerCrop" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:gravity="center_vertical"
android:orientation="vertical"
android:paddingLeft="5dp" >
<TextView
android:id="#+id/app_name"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:textStyle="bold" />
<TextView
android:id="#+id/app_paackage"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical" />
</LinearLayout>
</LinearLayout>
XML for the last activity:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/rootLayout"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:background="#android:color/white"
android:orientation="vertical" >
<GridView
android:id="#+id/gridview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:columnWidth="90dp"
android:gravity="center"
android:horizontalSpacing="10dp"
android:numColumns="auto_fit"
android:stretchMode="columnWidth"
android:verticalSpacing="10dp" />
</LinearLayout>
A GridView is a collection of views in a grid. The Android system doesn't magically know what views you want to be in it. This is where the adapter comes in. By setting an adapter for a GridView, you tell the GridView several things about how you want it to display views including how many views there are and what each view looks like. So yes, all GridViews need adapters.
I have created a class MapView that draws some circles and lines representing a map, where you can touch a circle to change the color of it. If works as it should, but when I add the View to a Layout the touchlistener does not return any touches.
Here is my MainActivity.java
import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.*;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.RelativeLayout;
public class MainActivity extends Activity {
MapView mapView;
RelativeLayout mainLayout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mainLayout = new RelativeLayout(this);
mapView = new MapView(this);
mapView.findViewById(R.id.theMap2);
mapView.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_UP) {
float x = event.getX();
float y = event.getY();
System.out.println("Touch! X: " + x + ", Y: " + y);
mapView.touched(x, y);
return true;
}
return true;
}
});
setContentView(R.layout.activity_main2);
}
I can see that the mapView works by doing this: setContentView(mapView);
Here is activity_main2.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:layout_width="match_parent"
android:layout_height="match_parent">
<bus.com.ece602_bus.MapView
android:id="#+id/theMap2"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
What am I doing wrong? Why are the touches not registered?
setContentView(R.layout.activity_main2); creates a new layout with a new instance of MapView than the one you set the listener for.
I'm trying to create a custom view, a calendar. The views inside this component are inflated from a xml layout. I have studied several tutorials and three or four similar (or even identical) questions on stack overflow but nothing seems to work. I'd appreciate it if you could point out the problem. Thanks in advance and here are the codes.
kcalendar_view.xml // the layout for the custom view
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center" >
<Button
android:id="#+id/btnKCalendarNavLeft"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_margin="5dp"
android:background="#drawable/kcalendar_nav_button_bg"
android:text="<" />
<TextView
android:id="#+id/txvKCalendarNavTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="-"
android:textAppearance="?android:attr/textAppearanceMedium" />
<Button
android:id="#+id/btnKCalendarNavRight"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_margin="5dp"
android:background="#drawable/kcalendar_nav_button_bg"
android:text=">" />
</LinearLayout>
<GridView
android:id="#+id/gridViewKCalendar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:numColumns="7" >
</GridView>
</merge>
KCalendarView.java // the custom view's class
package ir.kcoder.KCalendarView;
import ir.kcoder.persiancalendarweather.R;
import java.util.Calendar;
import android.content.Context;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.GridView;
import android.widget.LinearLayout;
import com.samanpr.jalalicalendar.JalaliCalendar;
import com.samanpr.jalalicalendar.JalaliCalendar.YearMonthDate;
public class KCalendarView extends LinearLayout {
private YearMonthDate currentJalaliDate;
private int parentWidth, parentHeight;
private Button leftButton, rightButton;
private GridView gridView;
private KCalendarAdapter calendarAdapter;
private Context context;
private View inflated;
public KCalendarView(Context context) {
super(context);
}
public KCalendarView(Context context, AttributeSet attrs) {
super(context, attrs);
this.context = context;
setOrientation(LinearLayout.VERTICAL);
setGravity(Gravity.CENTER);
setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflated = inflater.inflate(R.layout.kcalendar_view, this, true);
}
#Override
protected void onFinishInflate() {
super.onFinishInflate();
init(getContext());
}
private void init(Context context) {
Calendar c = Calendar.getInstance();
YearMonthDate currentGregDate = new YearMonthDate(c.get(Calendar.YEAR), c.get(Calendar.MONTH), c.get(Calendar.DATE));
currentJalaliDate = JalaliCalendar.gregorianToJalali(currentGregDate);
leftButton = (Button)findViewById(R.id.btnKCalendarNavLeft);
rightButton = (Button)findViewById(R.id.btnKCalendarNavRight);
gridView = (GridView)findViewById(R.id.gridViewKCalendar);
if(gridView != null) {
calendarAdapter = new KCalendarAdapter(context, currentJalaliDate.getYear(),
currentJalaliDate.getMonth());
gridView.setAdapter(calendarAdapter);
}
}
public void nextMonth() {
}
public void prevMonth() {
}
// #Override
// protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// parentWidth = MeasureSpec.getSize(widthMeasureSpec);
// parentHeight = MeasureSpec.getSize(heightMeasureSpec);
// this.setMeasuredDimension(parentWidth, parentHeight);
// super.onMeasure(widthMeasureSpec, heightMeasureSpec);
// }
#Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
// TODO Auto-generated method stub
}
}
activity_main.xml // I use this tag to include the custom view in my app
<ir.kcoder.KCalendarView.KCalendarView
android:id="#+id/kCalendarView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true" >
</ir.kcoder.KCalendarView.KCalendarView>
Updated
Try this I think it should work
public class KCalendarView extends LinearLayout {
private YearMonthDate currentJalaliDate;
private int parentWidth, parentHeight;
private Button leftButton, rightButton;
private GridView gridView;
private KCalendarAdapter calendarAdapter;
public KCalendarView(Context context, AttributeSet attrs) {
super(context, attrs);
doInflate();
}
private void doInflate() {
setOrientation(LinearLayout.VERTICAL);
setGravity(Gravity.CENTER);
setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
inflate(getContext(), R.layout.kcalendar_view, this);
leftButton = (Button)findViewById(R.id.btnKCalendarNavLeft);
rightButton = (Button)findViewById(R.id.btnKCalendarNavRight);
gridView = (GridView)findViewById(R.id.gridViewKCalendar);
init();
}
private void init() {
Calendar c = Calendar.getInstance();
YearMonthDate currentGregDate = new YearMonthDate(c.get(Calendar.YEAR), c.get(Calendar.MONTH), c.get(Calendar.DATE));
currentJalaliDate = JalaliCalendar.gregorianToJalali(currentGregDate);
calendarAdapter = new KCalendarAdapter(context, currentJalaliDate.getYear(), currentJalaliDate.getMonth());
gridView.setAdapter(calendarAdapter);
}
public void nextMonth() {
}
public void prevMonth() {
}
}
In my current project I run into an dead end. My custom view, only created to show a specific color, won't show in the view of my emulator (although it seems to show up correctly in the editor of Eclipse) except if it had a minimum height, but then it only get this exact height. I want it to match_parent.
The problem might be that it is in the item layout of a list view.
That's the code of my Custom View:
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
public class ColorView extends View {
private int mColor;
private Context mContext;
private int width;
private int height;
public ColorView(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.ColorView, 0, 0);
try {
mColor = a.getColor(R.styleable.ColorView_color, 0xFFFFFF);
} finally {
a.recycle();
}
}
public void setColor(int hexColor) {
mColor = hexColor;
invalidate();
}
public void setColorFromResource(int resID) {
mColor = mContext.getResources().getColor(resID);
invalidate();
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
Log.d("DEBUG", Integer.toString(w) + " " + Integer.toString(h));
width = w;
height = h;
}
#Override
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawColor(mColor);
Log.d("DEBUG", "drawn");
}
}
And a simplified version of my layout file:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:raabeapp="http://schemas.android.com/apk/res/com.example.myapp"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/row_view"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<com.example.myapp.ColorView
android:id="#+id/status_view"
android:layout_width="20dip"
android:layout_height="match_parent"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:layout_marginRight="5dip"
android:minHeight="50dp"
raabeapp:color="#FF0000" />
<TextView
android:id="#+id/hour_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toRightOf="#+id/status_view"
android:text="1"
android:textSize="#dimen/hour_textsize"
android:width="70dp" />
<TextView
android:id="#+id/text_hourtext"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toRightOf="#+id/hour_view"
android:text="#string/hour_text"
android:textSize="#dimen/hourtext_textsize" />
Ok, I figured out a workaround:
When I use a LinearLayout instead of a RelativeLayout I get the result I want.
It seems that the problem lies in the RelativeLayout. If someone knows why this is, or how I could still use a RelativeLayout I would be very interested. This answer does not provide a full solution, but in case someone runs into my problem it could provide a ugly workaround.
Use android:layout_height="match_parent" for your RelativeLayout.