0

I had an activity with a Listview containing text and green squares. I finally changed my mind and modified my code to use a fragment instead of an activity. But then my text color changed and I can't see the green squares anymore. I didn't changed anything in my list code or the color of the text so I don't understand what's happening.

Thank you for your help.

enter image description here

MainActivity is only used as a fragment container :

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        FragmentManager fm = getSupportFragmentManager();

        Fragment fragment = fm.findFragmentById(R.id.ll_container);
        if (fragment == null) {
            fragment = new PollutionLevelsFragment();
            fm.beginTransaction()
                    .add(R.id.ll_container, fragment)
                    .commit();
        }
    }
}

MainActivity layout

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
         android:id="@+id/ll_container"
         android:layout_width="match_parent"
         android:layout_height="match_parent" />

The fragment class

public class PollutionLevelsFragment extends Fragment implements PollutionLevelsFragmentMVP.View {
    private PollutionLevelAdapter plAdapter;

    @BindString(R.string.city)
    String city;

    @BindString(R.string.aqicn_token)
    String authToken;


    @BindView(R.id.lv_pollution_levels)
    ListView lvPollutionLevels;

    @Inject
    PollutionLevelsFragmentMVP.Presenter presenter;

    private ViewModel pollutionData;
    private ArrayList<String> testbidon;

    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_pollution_levels, container, false);

        ButterKnife.bind(this,view);

        // Construct the data source
        ArrayList<PollutionLevel> arrayOfPollutionLevel = new ArrayList<>();
        // Create the adapter to convert the array to views
        plAdapter = new PollutionLevelAdapter(getActivity().getApplicationContext(), arrayOfPollutionLevel);

        lvPollutionLevels.setAdapter(plAdapter);
        return view;

    }

    @Override
    public void onStart() {
        super.onStart();

        presenter.setView(this);
        presenter.loadData(city, authToken);
    }

    @Override
    public void onStop() {
        super.onStop();
        presenter.rxUnsubscribe();
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

        ((App) getActivity().getApplication()).getComponent().inject(this);
    }

    @Override
    public void updateData(ViewModel viewModel) {
        this.pollutionData = viewModel;

        ArrayList<PollutionLevel> pollutionLevels = viewModel.getAllPolluants();

        for(PollutionLevel pl : pollutionLevels) {
            plAdapter.add(pl);
        }
    }
}

The fragment layout

 <FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <ListView android:id="@+id/lv_pollution_levels"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
</FrameLayout>

The ArrayAdapter for the ListView

public class PollutionLevelAdapter extends ArrayAdapter<PollutionLevel> {

@BindView(R.id.tv_name)
TextView tvName;

@BindView(R.id.tv_value)
TextView tvValue;

public PollutionLevelAdapter(Context context, ArrayList<PollutionLevel> pollutionLevels) {
    super(context,0,pollutionLevels);
}


@Override
public View getView(int position, View convertView, ViewGroup parent) {
    if(convertView == null) {
        convertView = LayoutInflater.from(getContext()).inflate(R.layout.list_item_pollution, parent, false);
    }

    View view = convertView;

    ButterKnife.bind(this,view);
    PollutionLevel pollutionLevel = getItem(position);
    tvName.setText(pollutionLevel.getName());
    tvValue.setText(pollutionLevel.getValue());


    return view;
}
}

My list item

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
          xmlns:app="http://schemas.android.com/apk/res-auto"
          android:orientation="horizontal"
          android:layout_width="match_parent"
          android:layout_height="match_parent">

<ImageView
    android:id="@+id/iv_warning"
    android:layout_width="20dp"
    android:layout_height="20dp"
    app:srcCompat="@drawable/rectangle"/>

<TextView
    android:id="@+id/tv_name"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_margin="5dp"
    android:gravity="center_vertical"
    android:text="TextView"/>

<TextView
    android:id="@+id/tv_value"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_margin="5dp"
    android:gravity="center_vertical"
    android:text="TextView"/>

This is the code of the layout the Activity class that rendered the Listview correctly (so before I switched from an activity to a fragment). I didn't put the code of the Listview adapter here since it didn't change :

Activity

public class PollutionLevelsActivity extends AppCompatActivity implements PollutionLevelsActivityMVP.View {
    private PollutionLevelAdapter plAdapter;

    @BindString(R.string.city)
    String city;

    @BindString(R.string.aqicn_token)
    String authToken;


    @BindView(R.id.lv_pollution_levels)
    ListView lvPollutionLevels;

    @Inject
    PollutionLevelsActivityMVP.Presenter presenter;

    private ViewModel pollutionData;
    private ArrayList<String> testbidon;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ((App) getApplication()).getComponent().inject(this);
        ButterKnife.bind(this);

    // Construct the data source
    ArrayList<PollutionLevel> arrayOfPollutionLevel = new ArrayList<>();
    // Create the adapter to convert the array to views
    plAdapter = new PollutionLevelAdapter(this, arrayOfPollutionLevel);

    lvPollutionLevels.setAdapter(plAdapter);

    }

    @Override
    protected void onStart() {
        super.onStart();

        presenter.setView(this);
        presenter.loadData(city, authToken);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        presenter.rxUnsubscribe();
    }

    @Override
    public void updateData(ViewModel viewModel) {
        this.pollutionData = viewModel;

        ArrayList<PollutionLevel> pollutionLevels = viewModel.getAllPolluants();

        for(PollutionLevel pl : pollutionLevels) {
            plAdapter.add(pl);
        }
    }
}

Layout

<android.support.constraint.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"
    tools:context="com.livos.citypollution.pollutionlevels.PollutionLevelsActivity">

    <ListView
        android:id="@+id/lv_pollution_levels"
        android:layout_width="368dp"
        android:layout_height="495dp"
        tools:layout_editor_absoluteX="8dp"
        tools:layout_editor_absoluteY="8dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"/>

</android.support.constraint.ConstraintLayout>
Laurent
  • 1,661
  • 16
  • 29
  • I just resolved the problem of the squares that didn't appears by changing this `app:srcCompat="@drawable/rectangle"` to this `android:src="@drawable/rectangle"`. I still have problem with the text color. – Laurent Apr 17 '17 at 03:51

2 Answers2

0

To change Text Color add this

android:textColor="Your Color Code"

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
          xmlns:app="http://schemas.android.com/apk/res-auto"
          android:orientation="horizontal"
          android:layout_width="match_parent"
          android:layout_height="match_parent">

<ImageView
    android:id="@+id/iv_warning"
    android:layout_width="20dp"
    android:layout_height="20dp"
    **app:src="@drawable/rectangle"**/>

<TextView
    android:id="@+id/tv_name"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_margin="5dp"
    android:gravity="center_vertical"
    android:text="TextView"
    android:textColor="Your Color Code"/>

<TextView
    android:id="@+id/tv_value"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_margin="5dp"
    android:gravity="center_vertical"
    android:text="TextView"
    android:textColor="Your Color Code"/>
RAJESH KUMAR ARUMUGAM
  • 1,560
  • 21
  • 35
  • Yes, but the thing is normally there is a default color that is black if you don't give specific color. But I think I get it now, I think it's something to do with the theme that doesn't apply in the fragment but applies in the activity. Or a different theme apply... – Laurent Apr 17 '17 at 04:11
  • Yes, but do you know if there is a way to apply the theme use in the activiy to my fragment ? (if it's really a theme problem) – Laurent Apr 17 '17 at 04:27
  • 1
    And I think theme defined in Manifest only apply to activity not fragment. I think I found something here http://stackoverflow.com/questions/9469174/set-theme-for-a-fragment – Laurent Apr 17 '17 at 04:29
0

As i am getting. You give an adapter like:

public class PollutionLevelAdapter extends ArrayAdapter<PollutionLevel> {

@BindView(R.id.tv_name)
TextView tvName;

@BindView(R.id.tv_value)
TextView tvValue;

public PollutionLevelAdapter(Context context, ArrayList<PollutionLevel> pollutionLevels) {
    super(context,0,pollutionLevels);
}


@Override
public View getView(int position, View convertView, ViewGroup parent) {
    if(convertView == null) {
        convertView = LayoutInflater.from(getContext()).inflate(R.layout.list_item_pollution, parent, false);
    }

    View view = convertView;

    ButterKnife.bind(this,view);
    PollutionLevel pollutionLevel = getItem(position);
    tvName.setText(pollutionLevel.getName());
    tvValue.setText(pollutionLevel.getValue());


    return view;
}
}

You are binding your two TextView not Your ImageView as you gave your list_item_pollution, which is having ImageView so bind your ImageView like:

@BindView(R.id.iv_warning)
ImageView iv_warning;

and in getView method set is as :

iv_warning.setBackgroundColor(Color.parseColor("your color code"));
singh.indolia
  • 1,292
  • 13
  • 26
  • As I know the ButterKnife @BindView is used to avoid the findViewById() boilerplate, if I don't need to change my square colors I don't need to use @BindView for my ImageView since the square and it's color is defined through the PollutionLevelAdapter that use my List item layout. This list item layout contains my imageview with a drawable src defined. The color is defined in this drawable src. By the way as put in my comment I resolved this just using `android:src="@drawable/rectangle"`. – Laurent Apr 17 '17 at 04:24
  • For the text color there is normally a default theme color, that is black if no one is specified. After some more research the problem I think is that there is a default theme in the activity that doesn't apply in the fragment but I don't know why. – Laurent Apr 17 '17 at 04:26