Revert Picker item original color (#25750)

Summary:
Since the Android's Picker implementation uses an ArrayAdapter,
it means that the views that were created may be reused for other items
in order to save memory. With this in mind, if one sets the Picker.Item
prop color for only certain items there might be an state that
some items that does not have the color set will end up appearing
with the wrong color. This happens because, this new item is
reusing a view of an item that had the color prop set.
In order to avoid this problem, once a new view is created
the ReactPickerAdapter will save the original color and
re-apply if the item does not have the color prop.

## Changelog

[Android] [Fixed] - Picker.Item displays wrong colors
Pull Request resolved: https://github.com/facebook/react-native/pull/25750

Test Plan:
On android execute the code below. Only the FIRST item should be red.

```javascript
import React from 'react';
import { StyleSheet, View, Picker } from 'react-native';

const values = new Array(100);

for (let i = 0; i < values.length; i += 1) {
  values[i] = (i * i).toString();
}

const App = () => {
  const [selected, setSelected] = React.useState(0);
  const onValueChange = React.useCallback((_, idx) => {
    setSelected(idx);
  }, []);
  return (
    <View style={styles.container}>
      <Picker onValueChange={onValueChange} selectedValue={values[selected]}>
        {values.map((v, i) => (
          <Picker.Item
            key={v}
            value={v}
            label={v}
            {...(!i ? { color: 'red' } : {})}
          />
        ))}
      </Picker>
    </View>
  );
};

export default App;

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    paddingHorizontal: 20,
  },
});

```

### Without the patch

You should see various items with the red color (when only the first one should be red)
![picker-not-working](https://user-images.githubusercontent.com/984610/61584012-fe902300-ab16-11e9-8131-62c471b7f753.gif)

### With the patch
Only the first item is red.

![picker-working](https://user-images.githubusercontent.com/984610/61584013-09e34e80-ab17-11e9-9ae0-95a513581779.gif)

Closes https://github.com/facebook/react-native/issues/25456

Differential Revision: D16430961

Pulled By: mdvacca

fbshipit-source-id: 48b41845d465df2e3dd34fc4a76950ddc75a010a
This commit is contained in:
Guilherme Iscaro 2019-07-23 23:35:11 -07:00 коммит произвёл Facebook Github Bot
Родитель e12800b119
Коммит 5b953e51fa
1 изменённых файлов: 9 добавлений и 1 удалений

Просмотреть файл

@ -1,6 +1,7 @@
package com.facebook.react.views.picker;
import android.content.Context;
import android.content.res.ColorStateList;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@ -36,12 +37,16 @@ class ReactPickerAdapter extends ArrayAdapter<ReactPickerItem> {
private View getView(int position, View convertView, ViewGroup parent, boolean isDropdown) {
ReactPickerItem item = getItem(position);
boolean isNew = false;
if (convertView == null) {
int layoutResId =
isDropdown
? android.R.layout.simple_spinner_dropdown_item
: android.R.layout.simple_spinner_item;
convertView = mInflater.inflate(layoutResId, parent, false);
// Save original text colors
convertView.setTag(((TextView) convertView).getTextColors());
isNew = true;
}
TextView textView = (TextView) convertView;
@ -50,9 +55,12 @@ class ReactPickerAdapter extends ArrayAdapter<ReactPickerItem> {
textView.setTextColor(mPrimaryTextColor);
} else if (item.color != null) {
textView.setTextColor(item.color);
} else if (textView.getTag() != null && !isNew) {
// In case the new item does not set the color prop, go back to the default one
textView.setTextColor((ColorStateList) textView.getTag());
}
return convertView;
return textView;
}
public @Nullable Integer getPrimaryTextColor() {