Android Studio: Place a progressBar under a TextView programatically - java

I am trying to make a cardView that containts a title, a progressBar and a subTitle.
I generate all these three at runtime and it works fine but when I use ConstraintLayout params to put the progressBar below title it doesn t work.
Here is the XML:
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/cardView"
android:id="#+id/activityContent"
android:foregroundGravity="center">
</androidx.constraintlayout.widget.ConstraintLayout>
And here is the Kotlin code:
fun createCardView(v:View,title:String,top: CardView,days:Int):CardView{
val cardView=CardView(requireContext())
val text=createTitle(title)
cardView.addView(text)
cardView.setBackgroundColor(Color.WHITE)
cardView.cardElevation=17f
cardView.id=ids
ids=ids+1
var layoutparams = ConstraintLayout.LayoutParams(
ConstraintLayout.LayoutParams.MATCH_PARENT,
ConstraintLayout.LayoutParams.WRAP_CONTENT,
)
layoutparams.setMargins(60,80,60,18)
cardView.setLayoutParams(layoutparams)
val item = v.findViewById(R.id.activityContent) as? ConstraintLayout
if (item != null) {
item.addView(cardView)
}
var par=cardView.layoutParams as? ConstraintLayout.LayoutParams
if (par != null) {
par.topToBottom=top.id
par.startToEnd=top.id
}
val progressBar=createProgressBar(title)
val subText=createSubTitle(title)
val params = RelativeLayout.LayoutParams(300, 150)
params.addRule(RelativeLayout.BELOW,subText.id)
cardView.addView(progressBar,params)
cardView.addView(subText)
reference.child(user).child(title).setValue(days)
return cardView
}
I am looking for something to set to cardView as I set "par" to cardView.

Related

Error "The specified child already has a parent" after LinearLayout.addView() and then Linearlayout.removeView()

I'm working on a project where I have a parent LinearLayout with id=linear_parent created on activity_main.xml. Inside this parent layout, n numbers of LinearLayouts are created programmatically base on user input at EditText (id=no_of_views_input).
And inside the each of these Linearlayouts, there are more child views (imageView, edit, button) created programmatically.
Suppose a user enters 4 no_of_views_input, the views heirarchy would be something like,
============
linear_parent
linearLayout //position 1
imageView
edit
button
linearLayout //position 2
imageView
edit
button
linearLayout //position 3
imageView
edit
button
linearLayout //position 4
imageView
edit
button
===========
After these layouts and views are created, I want to rearrange the LinearLayouts, base on user input from child id=edit.
Suppose the user enters 1 on edit at LinearLayout position 3 , what I want is, the current LinearLayout at position 3 must be added to position 1 along with its children, and finally remove the old Linearlayout which was at position 3. (would be currently at position 4 if indexes are shifted down).
activity_main.xml
<?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:gravity="center"
android:orientation="vertical">
<LinearLayout
android:id="#+id/linear_parent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:gravity="center"
android:orientation="vertical">
<!-- Views are added here programmatically -->
</LinearLayout>
<EditText
android:id="#+id/no_of_views_input"
android:layout_width="100dp"
android:layout_height="40dp"
android:hint="Number of view to add"/>
<Button
android:id="#+id/add_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Add"/>
</LinearLayout>
MainActivity.java
public class MainActivity extends AppCompatActivity {
LinearLayout linear_parent;
Button add_button;
EditText no_of_views_input;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
linear_parent = findViewById(R.id.linear_parent);
add_button= findViewById(R.id.add_button);
no_of_views_input= findViewById(R.id.no_of_views_input);
no_of_views_input.setInputType(InputType.TYPE_CLASS_NUMBER);
add_button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (!no_of_views_input.getText().toString().isEmpty()) {
String no_of_views_temp = no_of_views_input.getText().toString();
int no_of_views = Integer.parseInt(no_of_views_temp);
for (int i = 0; i < no_of_views; i++) {
LinearLayout linearLayout = new LinearLayout(MainActivity.this);
LinearLayout.LayoutParams lp_ll = new LinearLayout.LayoutParams(600, 1500);
lp_ll.setMargins(0, 50, 0, 0);
linearLayout.setOrientation(LinearLayout.VERTICAL);
linearLayout.setId(View.generateViewId()); // id = 1, 2, 3, 4, ...
int linearLayoutID = linearLayout.getId();
linearLayout.setLayoutParams(lp_ll);
ImageView imageView = new ImageView(MainActivity.this);
LinearLayout.LayoutParams lp_image = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 800);
imageView.setBackgroundColor(Color.Yellow);
imageView.setLayoutParams(lp_image);
EditText edit = new EditText(MainActivity.this);
LinearLayout.LayoutParams lp_edit = new LinearLayout.LayoutParams(300, ViewGroup.LayoutParams.WRAP_CONTENT);
edit.setBackgroundColor(Color.WHITE);
edit.setInputType(InputType.TYPE_CLASS_NUMBER);
edit.setHint("move to index");
edit.setLayoutParams(lp_edit);
Button button = new Button(MainActivity.this);
LinearLayout.LayoutParams lp_button= new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
button.setBackgroundColor(Color.BLUE);
button.setText("Move");
button.setLayoutParams(lp_button);
linear_parent.addView(linearLayout);
linearLayout.addView(imageView);
linearLayout.addView(edit);
linearLayout.addView(button);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String indexTarget_temp = edit.getText().toString();
int indexTarget = Integer.parseInt(indexTarget_temp );
int childCount = linear_parent.getChildCount();
int currentLinearLayoutPos = linear_parent.indexOfChild(linearLayout);
try {
linear_parent.addView(linearLayout, indexTarget - 1); //adding current linearLayout to indexTarget
//error occurs this line
linear_parent.removeView(linear_parent.getChildAt(currentLinearLayoutPos + 1)); //removing linearLayout at old index
}
catch(IllegalStateException e) {
e.printStackTrace();
}
}
});
}
}else {
Toast.makeText(MainActivity.this, "Enter index no", Toast.LENGTH_SHORT).show();
}
}
});
}
}
The error I'm getting is
java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
Any help would be highly appreciated.
Try to remove the child from its parent before adding it as a subview:
try {
if (linearLayout.getParent() != null) {
// Remove child from parent
((ViewGroup) linearLayout.getParent()).removeView(linearLayout)
}
linear_parent.addView(linearLayout, indexTarget - 1);
}
catch(IllegalStateException e) {
e.printStackTrace();
}
However, consider switching to a RecyclerView.
It would simplify your code structure.

How do I use buttons inside fragments in Kotlin for android development?

I am new to android development and created a new project from android studio with a bottom navigation activity in Kotlin. Besides MainActivity.kt also dashboard, home and notifications Fragments and its ViewModels were generated. When I handle the button click inside the MainActivity class, everything works fine.
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val navView: BottomNavigationView = findViewById(R.id.nav_view)
val navController = findNavController(R.id.nav_host_fragment)
// Passing each menu ID as a set of Ids because each
// menu should be considered as top level destinations.
val appBarConfiguration = AppBarConfiguration(setOf(
R.id.navigation_home, R.id.navigation_dashboard, R.id.navigation_notifications))
setupActionBarWithNavController(navController, appBarConfiguration)
navView.setupWithNavController(navController)
//handle button click
val temporary_button = findViewById<Button>(R.id.temporary_button)
temporary_button.setOnClickListener{
makeText(this, "You clicked the button", LENGTH_LONG).show()
}
}
}
Here is the screenshot of a working button Button works fine
However I do not understand how to use the buttons inside different fragments. I tried to create a functionality for the second button inside a dashboard fragment Screenshot of a second button but I haven't found a solution. I have tried
class DashboardFragment : Fragment() {
private lateinit var dashboardViewModel: DashboardViewModel
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
dashboardViewModel =
ViewModelProviders.of(this).get(DashboardViewModel::class.java)
val root = inflater.inflate(R.layout.fragment_dashboard, container, false)
val textView: TextView = root.findViewById(R.id.text_dashboard)
dashboardViewModel.text.observe(this, Observer {
textView.text = it
})
//handle button click
val temporary_button = findViewById<Button>(R.id.temporary_button2)
temporary_button2.setOnClickListener{
makeText(this, "You clicked the button", LENGTH_LONG).show()
}
return root
}
}
but apperently this piece of code
//handle button click
val temporary_button = findViewById<Button>(R.id.temporary_button2)
temporary_button2.setOnClickListener{
makeText(this, "You clicked the button", LENGTH_LONG).show()
}
is wrong. Another thing that I have tried is changing the fragment_dashboard.xml file and setting the onClick property to a function name (android:onClick="button2click"). Here is the entire xml:
<androidx.constraintlayout.widget.ConstraintLayout
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" >
<TextView
android:id="#+id/text_dashboard"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:textAlignment="center"
android:textSize="20sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<Button
android:id="#+id/temporary_button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="192dp"
android:layout_marginBottom="248dp"
android:onClick="button2click"
android:text="Button2"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toStartOf="parent" />
I tried to use the function like this:
class DashboardFragment : Fragment() {
private lateinit var dashboardViewModel: DashboardViewModel
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
dashboardViewModel =
ViewModelProviders.of(this).get(DashboardViewModel::class.java)
val root = inflater.inflate(R.layout.fragment_dashboard, container, false)
val textView: TextView = root.findViewById(R.id.text_dashboard)
dashboardViewModel.text.observe(this, Observer {
textView.text = it
})
return root
}
fun button2click (view: View){
println("Button clicked")
}
}
but this way it doesn't work and the application crashes when I click the button.
Any help on how to use the buttons inside fragments would be appreceated.
This is what worked out for me in the end:
class DashboardFragment : Fragment() {
private lateinit var dashboardViewModel: DashboardViewModel
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
dashboardViewModel =
ViewModelProviders.of(this).get(DashboardViewModel::class.java)
val root = inflater.inflate(R.layout.fragment_dashboard, container, false)
val textView: TextView = root.findViewById(R.id.text_dashboard)
dashboardViewModel.text.observe(this, Observer {
textView.text = it
})
val button2 : Button = root.findViewById<Button>(R.id.temporary_button2)
button2.setOnClickListener{
println("clicked button 2")
Toast.makeText(view?.context, "Button Clicked", Toast.LENGTH_LONG).show()
}
return root
}
}
Try your inside onViewCreated instead of onCreateView using getView()/view.
e.g:
override fun onViewCreated(view: View?, savedInstanceState: Bundle?) {
val temporary_button = getView().findViewById<Button>(R.id.temporary_button2)
temporary_button2.setOnClickListener{
makeText(this, "You clicked the button", LENGTH_LONG).show()
}
}
There is no findViewById in fragment, normally inside a fragment you should override the onCreateView method, inflate your own layout and try to get views from the view you inflated. For example :
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
if (mContentView == null){
mContentView = inflater.inflate(R.layout.family_fragment_scene_list, container, false);
}
type = getArguments().getInt(ARGS_KEY_TYPE);
adapter = new SceneAdapter(getContext());
// get views from mContentView
mSceneList = (RecyclerView) mContentView.findViewById(R.id.swipe_target);
mSceneList.setLayoutManager(new LinearLayoutManager(getContext()));
mSceneList.setAdapter(adapter);
return mContentView;
}

Android Java create dynamic textviews

I am getting a json array through my api.
I want to display the data in my view, but I do not know how to generate for example textviews and put the data inside each views. (My wish would be to show the data in something like a html table, but at the moment I am fine to understand how to put the data in dynamic textviews
)
String id = jsonobject.getString("id");
String category = jsonobject.getString("category");
String content = jsonobject.getString("content");
Do hold the correct data.
Following method is in my Async task:
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
if(result != "error") {
JSONArray jsonArray;
TextView textview = (TextView) findViewById(R.id.jokeContent);
try {
jsonArray = new JSONArray(result);
for(int i=0; i < jsonArray.length(); i++) {
JSONObject jsonobject = jsonArray.getJSONObject(i);
String id = jsonobject.getString("id");
String category = jsonobject.getString("category");
String content = jsonobject.getString("content");
}
} catch (Exception e) {
Toasty.error(context, "Catch , test1!", Toast.LENGTH_SHORT, true).show();
}
} else {
Toasty.error(context, "Else , test2!", Toast.LENGTH_SHORT, true).show();
}
}
you can start by adding a table layout to your Layout, next create a row on your layout files something like this should work:
<?xml version="1.0" encoding="utf-8"?>
<TableRow xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/row">
<TextView
android:id="#+id/ID"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="20"
android:text="TextView" />
<TextView
android:id="#+id/Category"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="20"
android:text="TextView" />
<TextView
android:id="#+id/Content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="20"
android:text="TextView" />
</TableRow>
then you can add the rows and fill them with info like this on your activity by using an inflater
for(int i=0; i < jsonArray.length(); i++) {
JSONObject jsonobject = jsonArray.getJSONObject(i);
String id = jsonobject.getString("id");
String category = jsonobject.getString("category");
String content = jsonobject.getString("content");
TableLayout tableLayout = (TableLayout)findViewById(R.id.table);
TableRow tablerow = (TableRow)getLayoutInflater().inflate(R.layout.row, tableLayout,false);
((TextView)tablerow.findViewById(R.id.ID)).setText(id);
((TextView)tablerow.findViewById(R.id.Category)).setText(category);
((TextView)tablerow.findViewById(R.id.Content)).setText(content);
tableLayout.addView(tablerow);
}
hope it helps
If I understood your question correctly you want to create a textView and update it after getting a response of your Asynk task.
The idea is..
Create Activity (e.x. Main Activity), create AsynkTask
Create layout and TextView inside
Find TextView in Activity and not in Asynk task. In your case
TextView textview = (TextView) findViewById(R.id.jokeContent);
Put data to some common resource from AsyncTask and get them in Activity.
E.x. (Kotlin) through interface
interface AsyncResponse {
fun finishProcess(result: String)
}
...
class AsyncExecuter constructor(val asyncResp: AsyncResponse)
...
override fun onPostExecute(result: String) { //AsynkTask
super.onPostExecute(result)
asyncResp.finishProcess(result) //asynkResp is interfase which is put to AsynkTask constructor
}
Activity implements my own AsynkResp interface and calls AsynkTask
override fun onResume() {
super.onResume()
AsyncExecuter(this).execute()
}
And implement method from interface in activity where update TextView
override fun finishProcess(output: String) {
textview?.text = output
}
The main idea is manipulation with UI should be done from Activity and not from parallel threads.
In this example, i have created a list for a prefixed array list. Instead of XML i use java to create dynamic views.
public class MainActivity extends AppCompatActivity { String[] wordlist = new String[] { "Shahi Paneer", "Shahi Thali","Shahi Parantha","Kadai Paneer","Mix Parantha", }; #Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // setContentView(R.layout.activity_main); ListView list = new ListView(this); list.setBackgroundColor(Color.rgb(240,255,255) ); list.setAdapter(new MyAdapter(this, wordlist)); setContentView(list); } private class MyAdapter extends ArrayAdapter<String> { public MyAdapter(Context context, String[] strings) { super(context, -1, -1, strings); } #RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1) #Override public View getView(int position, View convertView, ViewGroup parent) { Typeface typeFace = Typeface.createFromAsset(getAssets(), "fonts/BLESD___ .ttf"); Typeface rupeeSymbol = Typeface.createFromAsset(getAssets(), "fonts/IndianRupee.ttf"); Typeface maze = Typeface.createFromAsset(getAssets(), "fonts/The Heart Maze Demo.ttf"); Typeface epicselfie = Typeface.createFromAsset(getAssets(), "fonts/My Epic Selfie Demo.ttf"); Typeface novaoval = Typeface.createFromAsset(getAssets(), "fonts/NovaOval.ttf"); LinearLayout listLayout = new LinearLayout(MainActivity.this); listLayout.setLayoutParams(new AbsListView.LayoutParams( AbsListView.LayoutParams.WRAP_CONTENT, AbsListView.LayoutParams.WRAP_CONTENT)); listLayout.setId(View.generateViewId()); listLayout.setOrientation(LinearLayout.VERTICAL); LinearLayout layout1 = new LinearLayout(MainActivity.this); layout1.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,LinearLayout.LayoutParams.WRAP_CONTENT)); layout1.setOrientation(LinearLayout.HORIZONTAL); listLayout.addView(layout1); ImageView imgView = new ImageView(MainActivity.this); imgView.setImageResource(R.drawable.thali); imgView.setPadding(20,20,20,10); imgView.setAdjustViewBounds(true); layout1.addView(imgView); LinearLayout layout2 = new LinearLayout(MainActivity.this); layout2.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT)); layout2.setOrientation(LinearLayout.HORIZONTAL); listLayout.addView(layout2); TextView listText = new TextView(MainActivity.this); listText.setTextColor(Color.BLACK); listText.setPadding(30,0,0,0); listText.setTextSize(TypedValue.COMPLEX_UNIT_SP, 40); listText.setTypeface(maze,maze.BOLD); listText.setId(View.generateViewId()); layout2.addView(listText); LinearLayout cartlayout = new LinearLayout(MainActivity.this); cartlayout.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT)); cartlayout.setOrientation(LinearLayout.HORIZONTAL); cartlayout.setPadding(0,0,30,0); cartlayout.setGravity(Gravity.RIGHT); // layout3.setPadding(0,10,0,20); layout2.addView(cartlayout); ImageView addCartView = new ImageView(MainActivity.this); addCartView.setImageResource(R.drawable.add); // addCartView.setPadding(200,0,0,0); cartlayout.addView(addCartView); TextView NOFProd = new TextView(MainActivity.this); NOFProd.setId(View.generateViewId()); NOFProd.setTypeface(rupeeSymbol); NOFProd.setPadding(10,20,10,0); NOFProd.setTextSize(TypedValue.COMPLEX_UNIT_SP, 25); // NOFProd.s NOFProd.setText("0"); cartlayout.addView(NOFProd); ImageView removeCartView = new ImageView(MainActivity.this); removeCartView.setImageResource(R.drawable.remove); // removeCartView.setPadding(20,5,20,0); cartlayout.addView(removeCartView); TextView descText = new TextView(MainActivity.this); descText.setTextColor(Color.DKGRAY); descText.setPadding(30,0,0,0); descText.setTextSize(TypedValue.COMPLEX_UNIT_SP, 20); descText.setTypeface(epicselfie); descText.setText("Swadist Bhojan"); descText.setId(View.generateViewId()); listLayout.addView(descText); // price and others Textview LinearLayout layout3 = new LinearLayout(MainActivity.this); layout3.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT)); layout3.setOrientation(LinearLayout.HORIZONTAL); layout3.setPadding(0,10,0,20); listLayout.addView(layout3); TextView pricesymbol = new TextView(MainActivity.this); pricesymbol.setId(View.generateViewId()); pricesymbol.setTypeface(rupeeSymbol); pricesymbol.setPadding(30,10,0,0); pricesymbol.setText("`"); layout3.addView(pricesymbol); TextView priceText = new TextView(MainActivity.this); priceText.setId(View.generateViewId()); priceText.setTypeface(novaoval); priceText.setPadding(10,10,0,0); priceText.setText(": 200"); layout3.addView(priceText); TextView rating = new TextView(MainActivity.this); rating.setId(View.generateViewId()); rating.setPadding(50,0,0,0); rating.setTypeface(novaoval); rating.setText("Rating : 3.5"); layout3.addView(rating); TextView any = new TextView(MainActivity.this); any.setPadding(50,0,0,0); any.setTypeface(novaoval); any.setId(View.generateViewId()); any.setText("anything "); layout3.addView(any); listText.setText(super.getItem(position)); return listLayout; } } }

Android RelativeLayout below another RelativeLayout dynamically

I'm trying to dynamically build relative layouts consisting of several images.
Theses relative layouts will be display below/rigth of previous relative layouts.
I'm starting with two relative layouts (rl100 and rl200). rl200 is below rl100.
But rl200 isn't below rl100, is "stacked" over rl100.
Can you help me ?
My code :
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RelativeLayout rLayout = (RelativeLayout) findViewById(R.id.rlayout);
RelativeLayout rL100 = rlAdd(rLayout,100,-1,-1);
ImageButton imgBtn101 = imgBtnAdd(rL100,101,R.drawable.apricot,-1,-1);
ImageButton imgBtn102 = imgBtnAdd(rL100,102,R.drawable.banana,-1,101);
ImageButton imgBtn103 = imgBtnAdd(rL100,103,R.drawable.cherry,101,-1);
ImageButton imgBtn104 = imgBtnAdd(rL100,104,R.drawable.strawberry,102,103);
RelativeLayout rL200 = rlAdd(rLayout,200,100,-1);
ImageButton imgBtn201 = imgBtnAdd(rL100,201,R.drawable.pineapple,-1,-1);
ImageButton imgBtn202 = imgBtnAdd(rL100,202,R.drawable.pineapple,-1,201);
ImageButton imgBtn203 = imgBtnAdd(rL100,203,R.drawable.pineapple,201,-1);
ImageButton imgBtn204 = imgBtnAdd(rL100,204,R.drawable.pineapple,202,203);
}
private RelativeLayout rlAdd(RelativeLayout parentContainer, int nId, int nIdBelow,
int nIdRightOf) {
RelativeLayout rLayout = new RelativeLayout(this);
rLayout.setId(nId);
RelativeLayout.LayoutParams rlp = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
if (nIdBelow != -1) {
rlp.addRule(RelativeLayout.BELOW, nIdBelow);
}
if (nIdRightOf != -1) {
rlp.addRule(RelativeLayout.RIGHT_OF, nIdRightOf);
}
rLayout.setLayoutParams(rlp);
parentContainer.addView(rLayout);
return rLayout;
}
private ImageButton imgBtnAdd(RelativeLayout ParentContainer, int ImgId, int ResDrawable,
int imgIdBelow, int imgIdRightOf) {
ImageButton imgBtn = new ImageButton(this);
imgBtn.setId(ImgId);
imgBtn.setImageResource(ResDrawable);
ParentContainer.addView(imgBtn);
RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) imgBtn.getLayoutParams();
if (imgIdBelow != -1) {
lp.addRule(RelativeLayout.BELOW, imgIdBelow);
}
if (imgIdRightOf != -1) {
lp.addRule(RelativeLayout.RIGHT_OF, imgIdRightOf);
}
imgBtn.setLayoutParams(lp);
return imgBtn;
}
}
activity_main.xml :
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" >
<RelativeLayout android:id="#+id/rlayout" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal">
</RelativeLayout>
</ScrollView>
You are doing wrong over here
RelativeLayout rL200 = rlAdd(rLayout,100,-1,-1);
// From method
if (nIdBelow != -1) {
rlp.addRule(RelativeLayout.BELOW, nIdBelow);
}
As you are not passing id in nIdBelow field how it is supposed to add layout below. pass above image id or use Linear Layout with vertical orientation.
You should use this line of code to add the relative layout with ID 200 below the relative layout with id 100, am I right?
RelativeLayout rL200 = rlAdd(rLayout, 200, 100, -1);
Thanks for your help.
I make differents errors :
RelativeLayout rL200...
RelativeLayout rL200 = rlAdd(rLayout, 200, 100, -1);
Correct version :
RelativeLayout rL200 = rlAdd(rLayout,200,100,-1);
ImageButton imgBtn20x
ImageButton imgBtn201 = imgBtnAdd(rL100,201,R.drawable.pineapple,-1,-1);
Correct version :
ImageButton imgBtn201 = imgBtnAdd(rL200,201,R.drawable.pineapple,-1,-1);
Same error for imgBtn202 ... imgBtn204
activity_main.xml
Errors 1 and 2 are stunning errors.
Third error in RelativeLayout android:id="#+id/rlayout" ...
Correct version :
<RelativeLayout android:id="#+id/rlayout" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_gravity="match_parent">
</RelativeLayout>

Clickable ListView

I'm looking now a few days for a solution for clickable items in a listView.
First I came across this:
developer.android.com/resources/articles/touch-mode.html
and found that it's doesn't have the "normal" onListItemClick() behavouir.
Then I came across of this code:
http://www.androidsnippets.org/snippets/125/
// LINE 296-321
#Override
protected ViewHolder createHolder(View v) {
// createHolder will be called only as long, as the ListView is not filled
// entirely. That is, where we gain our performance:
// We use the relatively costly findViewById() methods and
// bind the view's reference to the holder objects.
TextView text = (TextView) v.findViewById(R.id.listitem_text);
ImageView icon = (ImageView) v.findViewById(R.id.listitem_icon);
ViewHolder mvh = new MyViewHolder(text, icon);
// Additionally, we make some icons clickable
// Mind, that item becomes clickable, when adding a click listener (see API)
// so, it is not necessary to use the android:clickable attribute in XML
icon.setOnClickListener(new ClickableListAdapter.OnClickListener(mvh) {
public void onClick(View v, ViewHolder viewHolder) {
// we toggle the enabled state and also switch the icon
MyViewHolder mvh = (MyViewHolder) viewHolder;
MyData mo = (MyData) mvh.data;
mo.enable = !mo.enable; // toggle
ImageView icon = (ImageView) v;
icon.setImageBitmap(
mo.enable ? ClickableListItemActivity.this.mIconEnabled
: ClickableListItemActivity.this.mIconDisabled);
}
});
While debugging I noticed the parameter View v is a TextView and not a "normal" View and then of course:
TextView text = (TextView) v.findViewById(R.id.listitem_text);
returnes null and I get a NullPointerException...
Any ideas why? And how I can solve this?
Thanks in advance! :)
How do you create your instance of ClickableListAdapter ?
When you create your list adapter, you have to pass a resource id viewId, this should be a layout which will be inflated later.
public ClickableListAdapter(Context context, int viewid, List objects) {
// Cache the LayoutInflate to avoid asking for a new one each time.
mInflater = LayoutInflater.from(context);
mDataObjects = objects;
mViewId = viewid;
Below, the code inflate the xml layout passed to the constructor and call createHolder.
view = mInflater.inflate(mViewId, null);
// call the user's implementation
holder = createHolder(view);
So make sure that when instantiating your ClickableListAdapter, you pass a layout instead of an id
Edit
You have to create a xml layout with the following which is taken from the link you have provided:
<?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="wrap_content"
android:orientation="horizontal"
android:gravity="center_vertical"
>
<TextView android:text="Text" android:id="#+id/listitem_text"
android:layout_weight="1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
></TextView>
<ImageView android:id="#+id/listitem_icon"
android:src="#drawable/globe2_32x32"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxWidth="32px"
android:maxHeight="32px"
>
</ImageView>
</LinearLayout>
If you call it mylistrow.xml in the layout directory, so you construct your adapter as :
adapter = new MyClickableChannelListAdapter(this, R.layout.mylistrow, channelList);
setListAdapter(adapter);
List items should be clickable right out of the box. You can check how lists are coded by looking at ApiDemos project code. It should be present on your local machine since it is a part of the SDK. I have it at <root_sdk_folder>\platforms\android-2.0.1\samples\ApiDemos.

Categories