My Android game project needs a "New Game" activity. The game has a couple of options that should be asked each time a new game is started: the board size and the game seed. I would like to do this in a form resembling the standard "Settings" activity, but with an added "Start" button at the bottom. Given that these things will be chosen every new game, they don't want to be hidden away in the app's Settings activity. So what's the best way to go about this?
Things I've investigated:
Using a custom PreferenceActivity, since the behaviour is almost the same. Since the PreferenceActivity doesn't use layout XML files I can't see a way of adding a button to it.
A Linear layout that includes a ListView and a Button. I've started implementing this, but I can't even find a way to add items to the ListView - the ListView guide in the documentation certainly isn't aimed at a beginner like me! And then the list items need to be interactive to allow options to be selected: this looks like a lot of work to duplicate what PreferenceActivity almost does on its own.
Is there an option that I'm missing? I've spent a couple of hours trying to find an answer in the documentation and in previous questions, but with no progress. If anyone can point me in the right direction I'd be grateful.
Here is some code for you. Hope it will be useful.
You should go by the second way and use LinearLayout (this is main.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:orientation="vertical">
<ListView
android:id="#+id/lvSimple"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</ListView>
<Button // describe your start button here/>
</LinearLayout>
Layout for ListView item:
<?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="horizontal">
<ImageView
android:id="#+id/ivImg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_launcher">
</ImageView>
<LinearLayout
android:id="#+id/linearLayout1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical">
<CheckBox
android:id="#+id/cbChecked"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="CheckBox">
</CheckBox>
<TextView
android:id="#+id/tvText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:layout_marginRight="20dp"
android:text="TextView">
</TextView>
</LinearLayout>
</LinearLayout>
Your MainActivity.java:
public class MainActivity extends Activity {
// имена атрибутов для Map
final String ATTRIBUTE_NAME_TEXT = "text";
final String ATTRIBUTE_NAME_CHECKED = "checked";
final String ATTRIBUTE_NAME_IMAGE = "image";
ListView lvSimple;
/** Called when the activity is first created. */
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// data array
String[] texts = { "sometext 1", "sometext 2", "sometext 3",
"sometext 4", "sometext 5" };
boolean[] checked = { true, false, false, true, false };
int img = R.drawable.ic_launcher;
// our data source
ArrayList<Map<String, Object>> data = new ArrayList<Map<String, Object>>(
texts.length);
Map<String, Object> m;
for (int i = 0; i < texts.length; i++) {
m = new HashMap<String, Object>();
m.put(ATTRIBUTE_NAME_TEXT, texts[i]);
m.put(ATTRIBUTE_NAME_CHECKED, checked[i]);
m.put(ATTRIBUTE_NAME_IMAGE, img);
data.add(m);
}
String[] from = { ATTRIBUTE_NAME_TEXT, ATTRIBUTE_NAME_CHECKED,
ATTRIBUTE_NAME_IMAGE };
// array of IDs of Views
int[] to = { R.id.tvText, R.id.cbChecked, R.id.ivImg };
// create adapter
SimpleAdapter sAdapter = new SimpleAdapter(this, data, R.layout.item,
from, to);
// create ListView and set the adapter
lvSimple = (ListView) findViewById(R.id.lvSimple);
lvSimple.setAdapter(sAdapter);
}
}
Related
I am trying to create a LinearLayout programmatically from information contained in an Array.
Let me explain :
I create a professional application that will not be on PlayStore.
I have the following Array, manually populated, (a kind of global variable):
static final String[][] reseaux = new String[][] {
{"Net1","192.168.0.1"},
{"Net2","192.168.10.1"},
{"Net3","192.168.20.1"},
{"Net4","192.168.30.1"}
};
For some customers, it contains only one entry :
static final String[][] reseaux = new String[][] {
{"Net1","192.168.0.1"}
};
According to the Array containing only one entry, I created the following layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/welcome"
android:layout_gravity="center"
xmlns:android="http://schemas.android.com/apk/res/android"
tools:ignore="Overdraw">
<include
android:id="#+id/tool_bar"
layout="#layout/tool_bar" />
<ScrollView
android:layout_height="match_parent"
android:layout_width="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:id="#+id/linearLayout"
android:layout_marginTop="15dp"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:baselineAligned="false">
<LinearLayout
android:id="#+id/linearLayoutTest"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:orientation="vertical">
</LinearLayout>
</LinearLayout>
</LinearLayout>
</ScrollView>
</LinearLayout>
And the code :
LinearLayout l = findViewById(R.id.linearLayoutTest);
for (int i = 0; i < reseaux.length; ++i) {
final int id = i;
ImageButton resBtn = new ImageButton(this);
TextView tv = new TextView(this);
tv.setGravity(Gravity.CENTER | Gravity.BOTTOM);
tv.setText(reseaux[i][0]);
resBtn.setImageDrawable(ContextCompat.getDrawable(this, R.drawable.button_reseaux));
resBtn.setBackgroundColor(getResources().getColor(R.color.transparent));
l.addView(resBtn);
l.addView(tv);
resBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//Check network
if (CheckNetworkStatus.isNetworkAvailable(getApplicationContext())) {
Intent i = new Intent(getApplicationContext(),
HomeReseauActivity.class);
startActivity(i);
BASE_URL = null;
nomReseau = null;
BASE_URL = reseaux[id][1];
nomReseau = reseaux[id][0];
} else {
//Error message if no network connexion
if (toastMessage != null) toastMessage.cancel();
toastMessage = Toast.makeText(HomeActivity.this, getString(R.string.networkError), Toast.LENGTH_LONG);
toastMessage.show();
}
}
});
Give me the following result that suits me perfectly :
Now, when I have multiple entries in my Array, here's what I get :
This does not suit me. I will like horizontal lines of three icons. When a line is filled, it creates a new line of three icons, etc.
Here is a quick edit with paint to demonstrate what I want:
I think the solution must be simple .. but I can not get this result.
Be indulgent with my code, I learn everything by myself and there is surely a better way to write :-)
Hoping someone can help me!
As stated in the comments of my question, the solution was to use RecyclerView and GridLayoutManager.
For future readers, this link has helped me a lot!
Thanks to everyone who answered my question.
have problem with 'listView'. I searched everywhere but the problem does not arise none. Let me explain:
I have classic 'listview' in my 'layout':
<?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:orientation="vertical"
android:id="#+id/roza"
android:tileMode="repeat">
<ListView
android:id="#android:id/list"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#80ffffff"
android:alpha="200">
</ListView>
<TextView
android:id="#android:id/empty"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/no_todos" />
</LinearLayout>
And i create custom list_row xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="New Text"
android:id="#+id/list_name"
android:layout_alignParentTop="true"
android:textSize="25dp"
android:layout_alignParentStart="true"
android:layout_alignEnd="#+id/list_rune" />
------------bla bla bla -----------------
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="New Text"
android:layout_alignTop="#+id/list_date_update"
android:layout_toLeftOf="#+id/list_rune"
android:layout_toStartOf="#+id/list_rune"
android:id="#+id/textTester" />
</RelativeLayout>
My main class -
public class MainActivity extends ListActivity implements AdapterView.OnItemLongClickListener, SharedPreferences.OnSharedPreferenceChangeListener {
private NordBase dbHelper;
private Cursor cursor;
int rage = list_row; // my custom row
-------------------on create----------------
setContentView(R.layout.activity_main);
this.getListView().setDividerHeight(2);
dbHelper = new NordBase(this);
fillData();
------------------fillData-----------------
cursor = dbHelper.getAll();
startManagingCursor(cursor);
String[] from = new String[] { NordBase.NORD_NAME, NordBase.NORD_DESCRIPTION,
NordBase.NORD_PUNKTS, NordBase.NORD_PUNKTS_CROSS,
NordBase.NORD_DATE_CREATE, NordBase.NORD_DATE_UPDATE, NordBase.NORD_RUNE,
NordBase.NORD_IMPORTANT, NordBase.NORD_SUM };
int[] to = new int[] { R.id.list_name, R.id.list_description, R.id.list_punkts,
R.id.list_punkts_cross, R.id.list_date_create, R.id.list_date_update,
R.id.list_rune, R.id.list_important, R.id.list_sum, };
notes = new SimpleCursorAdapter(this,
rage, cursor, from, to);
setListAdapter(notes);
getListView().setOnItemLongClickListener(this);
Alas, I can not get to the items inside list_row, to bind them for comparison operators. for exp: if price == 0, then textview.setvisible = false...
I try LayoutInflater, but he make view element difrent from those in listview.
I try adapter binder class - but i think its no good for that.
Mostly i have an error - can't do that for the "null element"... that case - looks like all i ever do - my program can't findViewById elements in the list_row.
There is one point of contact
int[] to = new int[] { R.id.list_name, R.id.list_description, R.id.list_punkts,
R.id.list_punkts_cross, R.id.list_date_create, R.id.list_date_update,
R.id.list_rune, R.id.list_important, R.id.list_sum, };
notes = new SimpleCursorAdapter(this,
rage, cursor, from, to);
So help me Obi-Van Kenobi, and sorry for my dummy ENG, and i'm not sure that i past cod in right way)))
First of all your layout is not having the views which you have mention in the adapter like
R.id.list_description, R.id.list_punkts,
R.id.list_punkts_cross, R.id.list_date_create, R.id.list_date_update,
R.id.list_rune, R.id.list_important, R.id.list_sum
put this thing in the layout list_row xml
if you mean by ------------bla bla bla -----------------
this views than ok
also simpleCursorAdapter will not solve your purpose as you want to hide and show the views based on the data in respective views
so my first suggestion Change your layout to linearLayout or tableLayout or other layout as you feel and then do this in Your CustomAdapter class
like
class MyAdapter extends BaseAdapter
{
#Override
public View getView(int position, View convertView, ViewGroup parent) {
//here you infalteYour layout and and do your logical thing
//you can take your data out from cursor and store in the arrayList<YourModelClass> type and have better control
}
}
otherwise in relative layout just fill the data don't hide it so it may work but if you do hiding of some views chances are high it will not solve your problem
and typo mistake is there i hope so like
int[] to = new int[] { R.id.list_name, R.id.list_description, R.id.list_punkts,
R.id.list_punkts_cross, R.id.list_date_create, R.id.list_date_update,
R.id.list_rune, R.id.list_important, R.id.list_sum, };
//here no item but still u have written "," after R.id.list_sum this like "R.id.list_sum, "
notes = new SimpleCursorAdapter(this,
rage, cursor, from, to);
I've been trying to bind data to a drawerlayout over the past few days with no luck. I think my issue is the binding of the data and making sure that I have the correct parameters in the right spot. The code is below. For the purposes of this code, I have an array of items that I load from Resources.Array.NavigationItems. Once I have this in a string array, I iterate through the list, create a dictionary with an item, which is the text to be displayed, and an image, which is the image that I want to display. At this time, the image is just load from my resources's drawables. I then create two arrays. These two arrays should map to the necessary from (data in the javalist) and to (the id of the controls to display. When I run the code below, I get the error shown below the code. I am assuming that I have something wrong with my dictionary definitions. Suggestions are appreciated. Quite honestly, I'm not sure that I am creating the Dictionary or the List properly with the correct objects; my skills in translating from java to .net are probably lacking in this area.
_navigationItems = Resources.GetStringArray(Resource.Array.NavigationItems);
var mList = new List<IDictionary<string, object>>();
for(int i=0;i<_navigationItems.Length;i++){
var hm = new Dictionary<String,Object>();
hm.Add("item", _navigationItems[i]);
hm.Add("image", Resource.Drawable.aniswath);
mList.Add(hm);
}
var fromH = new string[]{ "item", "image" };
var toH = new int[] { Resource.Id.title, Resource.Id.icon };
_drawerList.Adapter = new SimpleAdapter (this, mList,
Resource.Layout.custom_drawer_item, fromH, toH);
Here are the contents of my Resource/Layout/custom_drawer_item.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="horizontal">
<ImageView
android:id="#+id/icon"
android:layout_width="25dp"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_marginLeft="12dp"
android:layout_marginRight="12dp"
android:src="#drawable/aniswath" />
<TextView
android:id="#+id/title"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_toRightOf="#id/icon"
android:minHeight="?android:attr/listPreferredItemHeightSmall"
android:textAppearance="?android:attr/textAppearanceListItemSmall"
android:textStyle="bold"
android:gravity="center_vertical"
android:paddingRight="40dp" />
</LinearLayout>
Error message determined from monitor:
04-11 21:40:50.022: E/AndroidRuntime(2515): java.lang.ClassCastException: mono.android.runtime.JavaObject cannot be cast to java.util.Map
04-11 21:40:50.022: E/AndroidRuntime(2515): at android.widget.SimpleAdapter.bindView(SimpleAdapter.java:147)
04-11 21:40:50.022: E/AndroidRuntime(2515): at android.widget.SimpleAdapter.createViewFromResource(SimpleAdapter.java:126)
I am trying to separate different columns of data that appear in my listview. The code for the adapter is as follows:
public class SQLiteDemo extends ListActivity {
private SQLiteDatabase database;
private CursorAdapter dataSource;
private static final String fields[] = { "firstname", "lastname", "resourceid", BaseColumns._ID };
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.second);
DatabaseHelper helper = new DatabaseHelper(this);
database = helper.getWritableDatabase();
Cursor data = database.query("cards", fields, null, null, null, null,
null);
dataSource = new SimpleCursorAdapter(this, R.layout.second, data, fields,
new int[] { R.id.firstname, R.id.secondname, R.id.name });
ListView view = getListView();
view.setHeaderDividersEnabled(true);
view.addHeaderView(getLayoutInflater().inflate(R.layout.second, null));
setListAdapter(dataSource);
I defined the listview in my layout file (do I need to do this for the inflater view?)
I have tried adding the dividers as follows....
<ListView android:id="#android:id/list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:visibility="visible"
android:divider = "#android:color/transparent"
android:dividerHeight ="10.sp" />
There does not seem to be any difference after adding the divider items; what am I doing wrong?
To be clear, I am a complete android noob, not looking for a complete answer (although they can be useful sometimes) just a nudge in the right direction would be more than enough. Thanks guys!
EDIT WITH R.layout.second
<?xml version="1.0" encoding="utf-8" ?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="wrap_content"
android:id="#+id/rowLayout"
android:orientation="horizontal"
android:layout_width="fill_parent">
<TextView android:layout_width="wrap_content"
android:layout_alignParentTop = "true"
android:layout_alignParentLeft="true"
android:layout_height="wrap_content"
android:id="#+id/firstname"
android:text="FirstName"/>
<TextView android:layout_width="wrap_content"
android:layout_toRightOf = "#+id/firstname"
android:layout_height="wrap_content"
android:id="#+id/secondname"
android:text="SecondName"
/>
<TextView android:layout_width="wrap_content"
android:layout_toRightOf = "#id/secondname"
android:layout_height="wrap_content"
android:id="#+id/name"
android:text="ResourceID"
/>
<ListView android:id="#android:id/list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:visibility="visible"
android:dividerHeight ="10.sp" />
</RelativeLayout>
I have removed the divider transparency now that I know what it does.
You have a misunderstanding. You are using the same Layout (R.layout.second) for two different things.
You need one Layout for the whole screen that contains a ListView (i.e. R.layout.second).
setContentView(R.layout.second)
And then you use an other Layout (i.e. mycell.xml) to define the looks of a sigle row in that ListView.
new SimpleCursorAdapter(this, R.layout.mycell, data, fields, new int[] { R.id.firstname, R.id.secondname, R.id.name });
The divider is drawn horizontally for each row in your database. You made it invisible.
If you want to have dividers between firstname,lastname , etc (for each column) you have to edit the Layout you are using for the rows (R.layout.mycell).
In my activity I do
TextView bTitle = (TextView)findViewById(R.id.TextView);
bTitle.setText(Html.fromHtml(title));
where title is a string
but i get a null pointer exception at second line ie. bTitle.setText(Html.fromHtml(title));
can anyone help???
Activity
public class NewsDetails extends ListActivity{
public static final String LOG_TAG = "Infra";
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.listplaceholder);
super.onStart();
Intent myIntent = getIntent();
String id = myIntent.getStringExtra("content_id");
String title = myIntent.getStringExtra("title");
//Spanned newTitle = Html.fromHtml(title);
//tv.setText(Html.fromHtml(title));
TextView bTitle = (TextView)findViewById(R.id.TextView);
Log.d(LOG_TAG, "What is the value: " + bTitle);
bTitle.setText(Html.fromHtml(title));
ArrayList<HashMap<String, String>> mylist = new ArrayList<HashMap<String, String>>();
String xml = XMLfunctions.getBodyXML(id);
String result = xml.replaceAll("<p>", "<p><div align=\"justify\">");
String nXml = result.replaceAll("</p>", "</div></p>");
TextView body = (TextView)findViewById(R.id.TextView1);
body.setText(Html.fromHtml(nXml));
//Spanned body = Html.fromHtml(nXml);
/*HashMap<String, String> map = new HashMap<String, String>();
map.put("title", tv.toString());
map.put("news", tv1.toString());
mylist.add(map);*/
/*ListAdapter adapter = new SimpleAdapter(this, mylist , R.layout.list_item, new String[] { "title", "news" }, new int[] { R.id.item_title, R.id.item_subtitle });
setListAdapter(adapter);
final ListView lv = getListView();
lv.setTextFilterEnabled(true);*/
}
Layout - listplaceholder.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ListView
android:id="#id/android:list"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:drawSelectorOnTop="false" />
<TextView
android:id="#id/android:empty"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="No data"
android:focusable="false"
android:clickable="true"/>
</LinearLayout>
text_view.xml
<LinearLayout android:id="#+id/LinearLayout01"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
xmlns:android="http://schemas.android.com/apk/res/android">
<TextView
android:id="#+id/TextView"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:textSize="16px"
android:textStyle="bold">
</TextView>
<TextView
android:id="#+id/TextView1"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:textSize="16px"
android:textStyle="bold">
</TextView>
</LinearLayout>
You should load the correct xml for your layout
setContentView(R.layout.text_view)
TextView bTitle = (TextView)findViewById(R.id.TextView);
bTitle.setText(Html.fromHtml(title));
i found two issue in your code
1)first thing is your TextView is not in listplaceholder.xml ..
so you it will be null pointer...
2)and you need add this code before setContentView();
Intent myIntent = getIntent();
String id = myIntent.getStringExtra("content_id");
String title = myIntent.getStringExtra("title");
and let me know what u want in list and where you call setAdapter for list , where is your adapter...
Make sure, that you actually have the
<TextView android:id="#+id/TextView [...]
view in your activity's layout xml.
Update
In your listplaceholder.xml there is no such TextView!
If you use the text_view.xml layout as your item renderer, then the code that tries to access the TextView should be placed inside your ListAdapter implementation's getView method!
1) Make sure R is imported from your project (and not from android.R namespace) in your import(s) section on the top
2) After the
TextView bTitle = (TextView)findViewById(R.id.TextView);
perform a log:
Log.d("debug", "bTitle: " + (bTitle != null));
and check out from terminal (if you're using Linux, if Windows, just run the logcat)
adb logcat | grep bTitle
This should tell you if you properly got the TextView from your layout (if it is present in the layout, like #rekaszeru mentioned).
3) Make sure the title variable is not null as well
Thank you all for your help. I have replaced textview with webview as i needed a lot of html formatting in my application and now my text appears in proper format and also my appliction is running fine.
Thanks